mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 15:34:13 +00:00 
			
		
		
		
	refactor(client): Use v-model for note component, freeze object
Related: #6595
This commit is contained in:
		
							parent
							
								
									cf43dd6ec5
								
							
						
					
					
						commit
						14b7f05af4
					
				
					 10 changed files with 111 additions and 70 deletions
				
			
		| 
						 | 
					@ -40,14 +40,14 @@
 | 
				
			||||||
			<x-note-header class="header" :note="appearNote" :mini="true"/>
 | 
								<x-note-header class="header" :note="appearNote" :mini="true"/>
 | 
				
			||||||
			<div class="body" ref="noteBody">
 | 
								<div class="body" ref="noteBody">
 | 
				
			||||||
				<p v-if="appearNote.cw != null" class="cw">
 | 
									<p v-if="appearNote.cw != null" class="cw">
 | 
				
			||||||
				<mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="emojis" v-once/>
 | 
									<mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" v-once/>
 | 
				
			||||||
					<x-cw-button v-model="showContent" :note="appearNote"/>
 | 
										<x-cw-button v-model="showContent" :note="appearNote"/>
 | 
				
			||||||
				</p>
 | 
									</p>
 | 
				
			||||||
				<div class="content" v-show="appearNote.cw == null || showContent">
 | 
									<div class="content" v-show="appearNote.cw == null || showContent">
 | 
				
			||||||
					<div class="text">
 | 
										<div class="text">
 | 
				
			||||||
						<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
 | 
											<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
 | 
				
			||||||
						<router-link class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><fa :icon="faReply"/></router-link>
 | 
											<router-link class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><fa :icon="faReply"/></router-link>
 | 
				
			||||||
						<mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="emojis" v-once/>
 | 
											<mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" v-once/>
 | 
				
			||||||
						<a class="rp" v-if="appearNote.renote != null">RN:</a>
 | 
											<a class="rp" v-if="appearNote.renote != null">RN:</a>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					<div class="files" v-if="appearNote.files.length > 0">
 | 
										<div class="files" v-if="appearNote.files.length > 0">
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,7 @@
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
			<footer class="footer">
 | 
								<footer class="footer">
 | 
				
			||||||
				<x-reactions-viewer :note="appearNote" :reactions="reactions" :my-reaction="myReaction" :emojis="emojis" ref="reactionsViewer"/>
 | 
									<x-reactions-viewer :note="appearNote" ref="reactionsViewer"/>
 | 
				
			||||||
				<button @click="reply()" class="button _button">
 | 
									<button @click="reply()" class="button _button">
 | 
				
			||||||
					<template v-if="appearNote.reply"><fa :icon="faReplyAll"/></template>
 | 
										<template v-if="appearNote.reply"><fa :icon="faReplyAll"/></template>
 | 
				
			||||||
					<template v-else><fa :icon="faReply"/></template>
 | 
										<template v-else><fa :icon="faReply"/></template>
 | 
				
			||||||
| 
						 | 
					@ -71,10 +71,10 @@
 | 
				
			||||||
				<button v-else class="button _button">
 | 
									<button v-else class="button _button">
 | 
				
			||||||
					<fa :icon="faBan"/>
 | 
										<fa :icon="faBan"/>
 | 
				
			||||||
				</button>
 | 
									</button>
 | 
				
			||||||
				<button v-if="!isMyNote && myReaction == null" class="button _button" @click="react()" ref="reactButton">
 | 
									<button v-if="!isMyNote && appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
 | 
				
			||||||
					<fa :icon="faPlus"/>
 | 
										<fa :icon="faPlus"/>
 | 
				
			||||||
				</button>
 | 
									</button>
 | 
				
			||||||
				<button v-if="!isMyNote && myReaction != null" class="button _button reacted" @click="undoReact()" ref="reactButton">
 | 
									<button v-if="!isMyNote && appearNote.myReaction != null" class="button _button reacted" @click="undoReact(appearNote)" ref="reactButton">
 | 
				
			||||||
					<fa :icon="faMinus"/>
 | 
										<fa :icon="faMinus"/>
 | 
				
			||||||
				</button>
 | 
									</button>
 | 
				
			||||||
				<button class="button _button" @click="menu()" ref="menuButton">
 | 
									<button class="button _button" @click="menu()" ref="menuButton">
 | 
				
			||||||
| 
						 | 
					@ -116,6 +116,11 @@ import copyToClipboard from '../scripts/copy-to-clipboard';
 | 
				
			||||||
import { checkWordMute } from '../scripts/check-word-mute';
 | 
					import { checkWordMute } from '../scripts/check-word-mute';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Vue.extend({
 | 
					export default Vue.extend({
 | 
				
			||||||
 | 
						model: {
 | 
				
			||||||
 | 
							prop: 'note',
 | 
				
			||||||
 | 
							event: 'updated'
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	components: {
 | 
						components: {
 | 
				
			||||||
		XSub,
 | 
							XSub,
 | 
				
			||||||
		XNoteHeader,
 | 
							XNoteHeader,
 | 
				
			||||||
| 
						 | 
					@ -152,9 +157,6 @@ export default Vue.extend({
 | 
				
			||||||
			showContent: false,
 | 
								showContent: false,
 | 
				
			||||||
			isDeleted: false,
 | 
								isDeleted: false,
 | 
				
			||||||
			muted: false,
 | 
								muted: false,
 | 
				
			||||||
			myReaction: null,
 | 
					 | 
				
			||||||
			reactions: {},
 | 
					 | 
				
			||||||
			emojis: [],
 | 
					 | 
				
			||||||
			noteBody: this.$refs.noteBody,
 | 
								noteBody: this.$refs.noteBody,
 | 
				
			||||||
			faEdit, faBolt, faTimes, faBullhorn, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faBiohazard, faPlug
 | 
								faEdit, faBolt, faTimes, faBullhorn, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faBiohazard, faPlug
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
| 
						 | 
					@ -211,7 +213,9 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		reactionsCount(): number {
 | 
							reactionsCount(): number {
 | 
				
			||||||
			return sum(Object.values(this.reactions));
 | 
								return this.appearNote.reactions
 | 
				
			||||||
 | 
									? sum(Object.values(this.appearNote.reactions))
 | 
				
			||||||
 | 
									: 0;
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		urls(): string[] {
 | 
							urls(): string[] {
 | 
				
			||||||
| 
						 | 
					@ -242,9 +246,8 @@ export default Vue.extend({
 | 
				
			||||||
			this.connection = this.$root.stream;
 | 
								this.connection = this.$root.stream;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.emojis = [...this.appearNote.emojis];
 | 
							console.log(this.note);
 | 
				
			||||||
		this.reactions = { ...this.appearNote.reactions };
 | 
					
 | 
				
			||||||
		this.myReaction = this.appearNote.myReaction;
 | 
					 | 
				
			||||||
		this.muted = await checkWordMute(this.appearNote, this.$store.state.i, this.$store.state.settings.mutedWords);
 | 
							this.muted = await checkWordMute(this.appearNote, this.$store.state.i, this.$store.state.settings.mutedWords);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (this.detail) {
 | 
							if (this.detail) {
 | 
				
			||||||
| 
						 | 
					@ -284,6 +287,19 @@ export default Vue.extend({
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
 | 
							updateAppearNote(v) {
 | 
				
			||||||
 | 
								this.$emit('updated', Object.freeze(this.isRenote ? {
 | 
				
			||||||
 | 
									...this.note,
 | 
				
			||||||
 | 
									renote: {
 | 
				
			||||||
 | 
										...this.note.renote,
 | 
				
			||||||
 | 
										...v
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} : {
 | 
				
			||||||
 | 
									...this.note,
 | 
				
			||||||
 | 
									...v
 | 
				
			||||||
 | 
								}));
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		readPromo() {
 | 
							readPromo() {
 | 
				
			||||||
			(this as any).$root.api('promo/read', {
 | 
								(this as any).$root.api('promo/read', {
 | 
				
			||||||
				noteId: this.appearNote.id
 | 
									noteId: this.appearNote.id
 | 
				
			||||||
| 
						 | 
					@ -320,47 +336,83 @@ export default Vue.extend({
 | 
				
			||||||
				case 'reacted': {
 | 
									case 'reacted': {
 | 
				
			||||||
					const reaction = body.reaction;
 | 
										const reaction = body.reaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// DeepではなくShallowコピーであることに注意。n.reactions[reaction] = hogeとかしないように(親からもらったデータをミューテートすることになるので)
 | 
				
			||||||
 | 
										let n = {
 | 
				
			||||||
 | 
											...this.appearNote,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (body.emoji) {
 | 
										if (body.emoji) {
 | 
				
			||||||
						if (!this.emojis.includes(body.emoji)) {
 | 
											const emojis = this.appearNote.emojis || [];
 | 
				
			||||||
							this.emojis.push(body.emoji);
 | 
											if (!emojis.includes(body.emoji)) {
 | 
				
			||||||
 | 
												n.emojis = [...emojis, body.emoji];
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (this.reactions[reaction] == null) {
 | 
										// TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる
 | 
				
			||||||
						Vue.set(this.reactions, reaction, 0);
 | 
										const currentCount = (this.appearNote.reactions || {})[reaction] || 0;
 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					// Increment the count
 | 
										// Increment the count
 | 
				
			||||||
					this.reactions[reaction]++;
 | 
										n.reactions = {
 | 
				
			||||||
 | 
											...this.appearNote.reactions,
 | 
				
			||||||
 | 
											[reaction]: currentCount + 1
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (body.userId === this.$store.state.i.id) {
 | 
										if (body.userId === this.$store.state.i.id) {
 | 
				
			||||||
						this.myReaction = reaction;
 | 
											n.myReaction = reaction;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										this.updateAppearNote(n);
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				case 'unreacted': {
 | 
									case 'unreacted': {
 | 
				
			||||||
					const reaction = body.reaction;
 | 
										const reaction = body.reaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (this.reactions[reaction] == null) {
 | 
										// DeepではなくShallowコピーであることに注意。n.reactions[reaction] = hogeとかしないように(親からもらったデータをミューテートすることになるので)
 | 
				
			||||||
						return;
 | 
										let n = {
 | 
				
			||||||
					}
 | 
											...this.appearNote,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる
 | 
				
			||||||
 | 
										const currentCount = (this.appearNote.reactions || {})[reaction] || 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					// Decrement the count
 | 
										// Decrement the count
 | 
				
			||||||
					if (this.reactions[reaction] > 0) this.reactions[reaction]--;
 | 
										n.reactions = {
 | 
				
			||||||
 | 
											...this.appearNote.reactions,
 | 
				
			||||||
 | 
											[reaction]: Math.max(0, currentCount - 1)
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (body.userId === this.$store.state.i.id) {
 | 
										if (body.userId === this.$store.state.i.id) {
 | 
				
			||||||
						this.myReaction = null;
 | 
											n.myReaction = null;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										this.updateAppearNote(n);
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				case 'pollVoted': {
 | 
									case 'pollVoted': {
 | 
				
			||||||
					const choice = body.choice;
 | 
										const choice = body.choice;
 | 
				
			||||||
					this.appearNote.poll.choices[choice].votes++;
 | 
					
 | 
				
			||||||
					if (body.userId === this.$store.state.i.id) {
 | 
										// DeepではなくShallowコピーであることに注意。n.reactions[reaction] = hogeとかしないように(親からもらったデータをミューテートすることになるので)
 | 
				
			||||||
						Vue.set(this.appearNote.poll.choices[choice], 'isVoted', true);
 | 
										let n = {
 | 
				
			||||||
 | 
											...this.appearNote,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										n.poll = {
 | 
				
			||||||
 | 
											...this.appearNote.poll,
 | 
				
			||||||
 | 
											choices: {
 | 
				
			||||||
 | 
												...this.appearNote.poll.choices,
 | 
				
			||||||
 | 
												[choice]: {
 | 
				
			||||||
 | 
													...this.appearNote.poll.choices[choice],
 | 
				
			||||||
 | 
													votes: this.appearNote.poll.choices[choice].votes + 1,
 | 
				
			||||||
 | 
													...(body.userId === this.$store.state.i.id ? {
 | 
				
			||||||
 | 
														isVoted: true
 | 
				
			||||||
 | 
													} : {})
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										this.updateAppearNote(n);
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -438,11 +490,11 @@ export default Vue.extend({
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		undoReact() {
 | 
							undoReact(note) {
 | 
				
			||||||
			const oldReaction = this.myReaction;
 | 
								const oldReaction = note.myReaction;
 | 
				
			||||||
			if (!oldReaction) return;
 | 
								if (!oldReaction) return;
 | 
				
			||||||
			this.$root.api('notes/reactions/delete', {
 | 
								this.$root.api('notes/reactions/delete', {
 | 
				
			||||||
				noteId: this.appearNote.id
 | 
									noteId: note.id
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<x-list ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed">
 | 
						<x-list ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed">
 | 
				
			||||||
		<x-note :note="note" :detail="detail" :key="note._featuredId_ || note._prId_ || note.id"/>
 | 
							<x-note :note="note" @updated="updated(note, $event)" :detail="detail" :key="note._featuredId_ || note._prId_ || note.id"/>
 | 
				
			||||||
	</x-list>
 | 
						</x-list>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<div v-show="more && !reversed" style="margin-top: var(--margin);">
 | 
						<div v-show="more && !reversed" style="margin-top: var(--margin);">
 | 
				
			||||||
| 
						 | 
					@ -62,14 +62,15 @@ export default Vue.extend({
 | 
				
			||||||
			default: false
 | 
								default: false
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		extract: {
 | 
							prop: {
 | 
				
			||||||
 | 
								type: String,
 | 
				
			||||||
			required: false
 | 
								required: false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	computed: {
 | 
						computed: {
 | 
				
			||||||
		notes(): any[] {
 | 
							notes(): any[] {
 | 
				
			||||||
			return this.extract ? this.extract(this.items) : this.items;
 | 
								return this.prop ? this.items.map(item => item[this.prop]) : this.items;
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		reversed(): boolean {
 | 
							reversed(): boolean {
 | 
				
			||||||
| 
						 | 
					@ -78,6 +79,15 @@ export default Vue.extend({
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
 | 
							updated(oldValue, newValue) {
 | 
				
			||||||
 | 
								const i = this.notes.findIndex(n => n === oldValue);
 | 
				
			||||||
 | 
								if (this.prop) {
 | 
				
			||||||
 | 
									Vue.set(this.items[i], this.prop, newValue);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									Vue.set(this.items, i, newValue);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		focus() {
 | 
							focus() {
 | 
				
			||||||
			this.$refs.notes.focus();
 | 
								this.$refs.notes.focus();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<button
 | 
					<button
 | 
				
			||||||
	class="hkzvhatu _button"
 | 
						class="hkzvhatu _button"
 | 
				
			||||||
	:class="{ reacted: myReaction == reaction, canToggle }"
 | 
						:class="{ reacted: note.myReaction == reaction, canToggle }"
 | 
				
			||||||
	@click="toggleReaction(reaction)"
 | 
						@click="toggleReaction(reaction)"
 | 
				
			||||||
	v-if="count > 0"
 | 
						v-if="count > 0"
 | 
				
			||||||
	@touchstart="onMouseover"
 | 
						@touchstart="onMouseover"
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@
 | 
				
			||||||
	ref="reaction"
 | 
						ref="reaction"
 | 
				
			||||||
	v-particle="canToggle"
 | 
						v-particle="canToggle"
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
	<x-reaction-icon :reaction="reaction" :custom-emojis="emojis" ref="icon"/>
 | 
						<x-reaction-icon :reaction="reaction" :custom-emojis="note.emojis" ref="icon"/>
 | 
				
			||||||
	<span>{{ count }}</span>
 | 
						<span>{{ count }}</span>
 | 
				
			||||||
</button>
 | 
					</button>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					@ -30,14 +30,6 @@ export default Vue.extend({
 | 
				
			||||||
			type: String,
 | 
								type: String,
 | 
				
			||||||
			required: true,
 | 
								required: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		myReaction: {
 | 
					 | 
				
			||||||
			type: String,
 | 
					 | 
				
			||||||
			required: false,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		emojis: {
 | 
					 | 
				
			||||||
			type: Array,
 | 
					 | 
				
			||||||
			required: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		count: {
 | 
							count: {
 | 
				
			||||||
			type: Number,
 | 
								type: Number,
 | 
				
			||||||
			required: true,
 | 
								required: true,
 | 
				
			||||||
| 
						 | 
					@ -79,7 +71,7 @@ export default Vue.extend({
 | 
				
			||||||
		toggleReaction() {
 | 
							toggleReaction() {
 | 
				
			||||||
			if (!this.canToggle) return;
 | 
								if (!this.canToggle) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const oldReaction = this.myReaction;
 | 
								const oldReaction = this.note.myReaction;
 | 
				
			||||||
			if (oldReaction) {
 | 
								if (oldReaction) {
 | 
				
			||||||
				this.$root.api('notes/reactions/delete', {
 | 
									this.$root.api('notes/reactions/delete', {
 | 
				
			||||||
					noteId: this.note.id
 | 
										noteId: this.note.id
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<div class="tdflqwzn" :class="{ isMe }">
 | 
					<div class="tdflqwzn" :class="{ isMe }">
 | 
				
			||||||
	<x-reaction v-for="(count, reaction) in reactions" :reaction="reaction" :count="count" :is-initial="initialReactions.has(reaction)" :note="note" :my-reaction="myReaction" :emojis="emojis" :key="reaction"/>
 | 
						<x-reaction v-for="(count, reaction) in note.reactions" :reaction="reaction" :count="count" :is-initial="initialReactions.has(reaction)" :note="note" :key="reaction"/>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,28 +12,16 @@ export default Vue.extend({
 | 
				
			||||||
	components: {
 | 
						components: {
 | 
				
			||||||
		XReaction
 | 
							XReaction
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						data() {
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								initialReactions: new Set(Object.keys(this.note.reactions))
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	props: {
 | 
						props: {
 | 
				
			||||||
		note: {
 | 
							note: {
 | 
				
			||||||
			type: Object,
 | 
								type: Object,
 | 
				
			||||||
			required: true
 | 
								required: true
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		reactions: {
 | 
					 | 
				
			||||||
			type: Object,
 | 
					 | 
				
			||||||
			required: true
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		myReaction: {
 | 
					 | 
				
			||||||
			type: String,
 | 
					 | 
				
			||||||
			required: false,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		emojis: {
 | 
					 | 
				
			||||||
			type: Array,
 | 
					 | 
				
			||||||
			required: true,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	data() {
 | 
					 | 
				
			||||||
		return {
 | 
					 | 
				
			||||||
			initialReactions: new Set(Object.keys(this.note.reactions))
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	computed: {
 | 
						computed: {
 | 
				
			||||||
		isMe(): boolean {
 | 
							isMe(): boolean {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,6 @@ export default Vue.extend({
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const prepend = note => {
 | 
							const prepend = note => {
 | 
				
			||||||
			Object.freeze(note);
 | 
					 | 
				
			||||||
			(this.$refs.tl as any).prepend(note);
 | 
								(this.$refs.tl as any).prepend(note);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.$emit('note');
 | 
								this.$emit('note');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
<div>
 | 
					<div>
 | 
				
			||||||
	<portal to="icon"><fa :icon="faStar"/></portal>
 | 
						<portal to="icon"><fa :icon="faStar"/></portal>
 | 
				
			||||||
	<portal to="title">{{ $t('favorites') }}</portal>
 | 
						<portal to="title">{{ $t('favorites') }}</portal>
 | 
				
			||||||
	<x-notes :pagination="pagination" :detail="true" :extract="items => items.map(item => item.note)" @before="before()" @after="after()"/>
 | 
						<x-notes :pagination="pagination" :detail="true" :prop="'note'" @before="before()" @after="after()"/>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -436,7 +436,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onStatsLog(statsLog) {
 | 
							onStatsLog(statsLog) {
 | 
				
			||||||
			for (const stats of statsLog.reverse()) {
 | 
								for (const stats of [...statsLog].reverse()) {
 | 
				
			||||||
				this.onStats(stats);
 | 
									this.onStats(stats);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,7 +169,7 @@ export default Vue.extend({
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onStatsLog(statsLog) {
 | 
							onStatsLog(statsLog) {
 | 
				
			||||||
			for (const stats of statsLog.reverse()) {
 | 
								for (const stats of [...statsLog].reverse()) {
 | 
				
			||||||
				this.onStats(stats);
 | 
									this.onStats(stats);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@
 | 
				
			||||||
		<hr v-if="showNext"/>
 | 
							<hr v-if="showNext"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<mk-remote-caution v-if="note.user.host != null" :href="note.url || note.uri" style="margin-bottom: var(--margin)"/>
 | 
							<mk-remote-caution v-if="note.user.host != null" :href="note.url || note.uri" style="margin-bottom: var(--margin)"/>
 | 
				
			||||||
		<x-note :note="note" :key="note.id" :detail="true"/>
 | 
							<x-note v-model="note" :key="note.id" :detail="true"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<button class="_panel _button" v-if="hasPrev && !showPrev" @click="showPrev = true" style="margin: var(--margin) auto 0 auto;"><fa :icon="faChevronDown"/></button>
 | 
							<button class="_panel _button" v-if="hasPrev && !showPrev" @click="showPrev = true" style="margin: var(--margin) auto 0 auto;"><fa :icon="faChevronDown"/></button>
 | 
				
			||||||
		<hr v-if="showPrev"/>
 | 
							<hr v-if="showPrev"/>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,10 +112,10 @@ export default class Stream extends EventEmitter {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (const c of connections.filter(c => c != null)) {
 | 
								for (const c of connections.filter(c => c != null)) {
 | 
				
			||||||
				c.emit(body.type, body.body);
 | 
									c.emit(body.type, Object.freeze(body.body));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			this.emit(type, body);
 | 
								this.emit(type, Object.freeze(body));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue