mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	
							parent
							
								
									b32737cdff
								
							
						
					
					
						commit
						b5a1fdd4c7
					
				
					 5 changed files with 73 additions and 70 deletions
				
			
		| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div
 | 
			
		||||
	class="note _panel"
 | 
			
		||||
	v-show="!isDeleted && !hideThisNote"
 | 
			
		||||
	v-show="!isDeleted"
 | 
			
		||||
	:tabindex="!isDeleted ? '-1' : null"
 | 
			
		||||
	:class="{ renote: isRenote }"
 | 
			
		||||
	v-hotkey="keymap"
 | 
			
		||||
| 
						 | 
				
			
			@ -37,16 +37,16 @@
 | 
			
		|||
		<mk-avatar class="avatar" :user="appearNote.user" v-once/>
 | 
			
		||||
		<div class="main">
 | 
			
		||||
			<x-note-header class="header" :note="appearNote" :mini="true"/>
 | 
			
		||||
			<div class="body" v-if="appearNote.deletedAt == null" ref="noteBody">
 | 
			
		||||
			<div class="body" ref="noteBody">
 | 
			
		||||
				<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="appearNote.emojis" v-once/>
 | 
			
		||||
				<mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="emojis" v-once/>
 | 
			
		||||
					<x-cw-button v-model="showContent" :note="appearNote"/>
 | 
			
		||||
				</p>
 | 
			
		||||
				<div class="content" v-show="appearNote.cw == null || showContent">
 | 
			
		||||
					<div class="text">
 | 
			
		||||
						<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>
 | 
			
		||||
						<mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" v-once/>
 | 
			
		||||
						<mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="emojis" v-once/>
 | 
			
		||||
						<a class="rp" v-if="appearNote.renote != null">RN:</a>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="files" v-if="appearNote.files.length > 0">
 | 
			
		||||
| 
						 | 
				
			
			@ -57,8 +57,8 @@
 | 
			
		|||
					<div class="renote" v-if="appearNote.renote"><x-note-preview :note="appearNote.renote"/></div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<footer v-if="appearNote.deletedAt == null" class="footer">
 | 
			
		||||
				<x-reactions-viewer :note="appearNote" ref="reactionsViewer"/>
 | 
			
		||||
			<footer class="footer">
 | 
			
		||||
				<x-reactions-viewer :note="appearNote" :reactions="reactions" :my-reaction="myReaction" :emojis="emojis" ref="reactionsViewer"/>
 | 
			
		||||
				<button @click="reply()" class="button _button">
 | 
			
		||||
					<template v-if="appearNote.reply"><fa :icon="faReplyAll"/></template>
 | 
			
		||||
					<template v-else><fa :icon="faReply"/></template>
 | 
			
		||||
| 
						 | 
				
			
			@ -70,17 +70,16 @@
 | 
			
		|||
				<button v-else class="button _button">
 | 
			
		||||
					<fa :icon="faBan"/>
 | 
			
		||||
				</button>
 | 
			
		||||
				<button v-if="!isMyNote && appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
 | 
			
		||||
				<button v-if="!isMyNote && myReaction == null" class="button _button" @click="react()" ref="reactButton">
 | 
			
		||||
					<fa :icon="faPlus"/>
 | 
			
		||||
				</button>
 | 
			
		||||
				<button v-if="!isMyNote && appearNote.myReaction != null" class="button _button reacted" @click="undoReact(appearNote)" ref="reactButton">
 | 
			
		||||
				<button v-if="!isMyNote && myReaction != null" class="button _button reacted" @click="undoReact()" ref="reactButton">
 | 
			
		||||
					<fa :icon="faMinus"/>
 | 
			
		||||
				</button>
 | 
			
		||||
				<button class="button _button" @click="menu()" ref="menuButton">
 | 
			
		||||
					<fa :icon="faEllipsisH"/>
 | 
			
		||||
				</button>
 | 
			
		||||
			</footer>
 | 
			
		||||
			<div class="deleted" v-if="appearNote.deletedAt != null">{{ $t('deleted') }}</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</article>
 | 
			
		||||
	<x-sub v-for="note in replies" :key="note.id" :note="note" class="reply" :detail="true"/>
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +141,10 @@ export default Vue.extend({
 | 
			
		|||
			conversation: [],
 | 
			
		||||
			replies: [],
 | 
			
		||||
			showContent: false,
 | 
			
		||||
			hideThisNote: false,
 | 
			
		||||
			isDeleted: false,
 | 
			
		||||
			myReaction: null,
 | 
			
		||||
			reactions: {},
 | 
			
		||||
			emojis: [],
 | 
			
		||||
			noteBody: this.$refs.noteBody,
 | 
			
		||||
			faEdit, faBolt, faTimes, faBullhorn, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faBiohazard, faPlug
 | 
			
		||||
		};
 | 
			
		||||
| 
						 | 
				
			
			@ -186,10 +188,6 @@ export default Vue.extend({
 | 
			
		|||
			return this.isRenote ? this.note.renote : this.note;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		isDeleted(): boolean {
 | 
			
		||||
			return this.appearNote.deletedAt != null || this.note.deletedAt != null;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		isMyNote(): boolean {
 | 
			
		||||
			return this.$store.getters.isSignedIn && (this.$store.state.i.id === this.appearNote.userId);
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			@ -203,9 +201,7 @@ export default Vue.extend({
 | 
			
		|||
		},
 | 
			
		||||
 | 
			
		||||
		reactionsCount(): number {
 | 
			
		||||
			return this.appearNote.reactions
 | 
			
		||||
				? sum(Object.values(this.appearNote.reactions))
 | 
			
		||||
				: 0;
 | 
			
		||||
			return sum(Object.values(this.reactions));
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		urls(): string[] {
 | 
			
		||||
| 
						 | 
				
			
			@ -232,6 +228,10 @@ export default Vue.extend({
 | 
			
		|||
	},
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
		this.emojis = [...this.appearNote.emojis];
 | 
			
		||||
		this.reactions = { ...this.appearNote.reactions };
 | 
			
		||||
		this.myReaction = this.appearNote.myReaction;
 | 
			
		||||
 | 
			
		||||
		if (this.$store.getters.isSignedIn) {
 | 
			
		||||
			this.connection = this.$root.stream;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -261,7 +261,7 @@ export default Vue.extend({
 | 
			
		|||
			this.connection.on('_connected_', this.onStreamConnected);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.noteBody = this.$refs.noteBody
 | 
			
		||||
		this.noteBody = this.$refs.noteBody;
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
| 
						 | 
				
			
			@ -277,7 +277,7 @@ export default Vue.extend({
 | 
			
		|||
			(this as any).$root.api('promo/read', {
 | 
			
		||||
				noteId: this.appearNote.id
 | 
			
		||||
			});
 | 
			
		||||
			this.hideThisNote = true;
 | 
			
		||||
			this.isDeleted = true;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		capture(withHandler = false) {
 | 
			
		||||
| 
						 | 
				
			
			@ -310,26 +310,20 @@ export default Vue.extend({
 | 
			
		|||
					const reaction = body.reaction;
 | 
			
		||||
 | 
			
		||||
					if (body.emoji) {
 | 
			
		||||
						const emojis = this.appearNote.emojis || [];
 | 
			
		||||
						if (!emojis.includes(body.emoji)) {
 | 
			
		||||
							emojis.push(body.emoji);
 | 
			
		||||
							Vue.set(this.appearNote, 'emojis', emojis);
 | 
			
		||||
						if (!this.emojis.includes(body.emoji)) {
 | 
			
		||||
							this.emojis.push(body.emoji);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (this.appearNote.reactions == null) {
 | 
			
		||||
						Vue.set(this.appearNote, 'reactions', {});
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (this.appearNote.reactions[reaction] == null) {
 | 
			
		||||
						Vue.set(this.appearNote.reactions, reaction, 0);
 | 
			
		||||
					if (this.reactions[reaction] == null) {
 | 
			
		||||
						Vue.set(this.reactions, reaction, 0);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// Increment the count
 | 
			
		||||
					this.appearNote.reactions[reaction]++;
 | 
			
		||||
					this.reactions[reaction]++;
 | 
			
		||||
 | 
			
		||||
					if (body.userId == this.$store.state.i.id) {
 | 
			
		||||
						Vue.set(this.appearNote, 'myReaction', reaction);
 | 
			
		||||
					if (body.userId === this.$store.state.i.id) {
 | 
			
		||||
						this.myReaction = reaction;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -337,19 +331,15 @@ export default Vue.extend({
 | 
			
		|||
				case 'unreacted': {
 | 
			
		||||
					const reaction = body.reaction;
 | 
			
		||||
 | 
			
		||||
					if (this.appearNote.reactions == null) {
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (this.appearNote.reactions[reaction] == null) {
 | 
			
		||||
					if (this.reactions[reaction] == null) {
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// Decrement the count
 | 
			
		||||
					if (this.appearNote.reactions[reaction] > 0) this.appearNote.reactions[reaction]--;
 | 
			
		||||
					if (this.reactions[reaction] > 0) this.reactions[reaction]--;
 | 
			
		||||
 | 
			
		||||
					if (body.userId == this.$store.state.i.id) {
 | 
			
		||||
						Vue.set(this.appearNote, 'myReaction', null);
 | 
			
		||||
					if (body.userId === this.$store.state.i.id) {
 | 
			
		||||
						this.myReaction = null;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -357,19 +347,14 @@ export default Vue.extend({
 | 
			
		|||
				case 'pollVoted': {
 | 
			
		||||
					const choice = body.choice;
 | 
			
		||||
					this.appearNote.poll.choices[choice].votes++;
 | 
			
		||||
					if (body.userId == this.$store.state.i.id) {
 | 
			
		||||
					if (body.userId === this.$store.state.i.id) {
 | 
			
		||||
						Vue.set(this.appearNote.poll.choices[choice], 'isVoted', true);
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				case 'deleted': {
 | 
			
		||||
					Vue.set(this.appearNote, 'deletedAt', body.deletedAt);
 | 
			
		||||
					Vue.set(this.appearNote, 'renote', null);
 | 
			
		||||
					this.appearNote.text = null;
 | 
			
		||||
					this.appearNote.fileIds = [];
 | 
			
		||||
					this.appearNote.poll = null;
 | 
			
		||||
					this.appearNote.cw = null;
 | 
			
		||||
					this.isDeleted = true;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -442,11 +427,11 @@ export default Vue.extend({
 | 
			
		|||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		undoReact(note) {
 | 
			
		||||
			const oldReaction = note.myReaction;
 | 
			
		||||
		undoReact() {
 | 
			
		||||
			const oldReaction = this.myReaction;
 | 
			
		||||
			if (!oldReaction) return;
 | 
			
		||||
			this.$root.api('notes/reactions/delete', {
 | 
			
		||||
				noteId: note.id
 | 
			
		||||
				noteId: this.appearNote.id
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -638,7 +623,7 @@ export default Vue.extend({
 | 
			
		|||
						this.$root.api('notes/delete', {
 | 
			
		||||
							noteId: this.note.id
 | 
			
		||||
						});
 | 
			
		||||
						Vue.set(this.note, 'deletedAt', new Date());
 | 
			
		||||
						this.isDeleted = true;
 | 
			
		||||
					}
 | 
			
		||||
				}],
 | 
			
		||||
				source: this.$refs.renoteTime,
 | 
			
		||||
| 
						 | 
				
			
			@ -925,10 +910,6 @@ export default Vue.extend({
 | 
			
		|||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			> .deleted {
 | 
			
		||||
				opacity: 0.7;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
<template>
 | 
			
		||||
<button
 | 
			
		||||
	class="hkzvhatu _button"
 | 
			
		||||
	:class="{ reacted: note.myReaction == reaction, canToggle }"
 | 
			
		||||
	:class="{ reacted: myReaction == reaction, canToggle }"
 | 
			
		||||
	@click="toggleReaction(reaction)"
 | 
			
		||||
	v-if="count > 0"
 | 
			
		||||
	@touchstart="onMouseover"
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
	ref="reaction"
 | 
			
		||||
	v-particle="canToggle"
 | 
			
		||||
>
 | 
			
		||||
	<x-reaction-icon :reaction="reaction" :custom-emojis="note.emojis" ref="icon"/>
 | 
			
		||||
	<x-reaction-icon :reaction="reaction" :custom-emojis="emojis" ref="icon"/>
 | 
			
		||||
	<span>{{ count }}</span>
 | 
			
		||||
</button>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +30,14 @@ export default Vue.extend({
 | 
			
		|||
			type: String,
 | 
			
		||||
			required: true,
 | 
			
		||||
		},
 | 
			
		||||
		myReaction: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: false,
 | 
			
		||||
		},
 | 
			
		||||
		emojis: {
 | 
			
		||||
			type: Array,
 | 
			
		||||
			required: true,
 | 
			
		||||
		},
 | 
			
		||||
		count: {
 | 
			
		||||
			type: Number,
 | 
			
		||||
			required: true,
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +79,7 @@ export default Vue.extend({
 | 
			
		|||
		toggleReaction() {
 | 
			
		||||
			if (!this.canToggle) return;
 | 
			
		||||
 | 
			
		||||
			const oldReaction = this.note.myReaction;
 | 
			
		||||
			const oldReaction = this.myReaction;
 | 
			
		||||
			if (oldReaction) {
 | 
			
		||||
				this.$root.api('notes/reactions/delete', {
 | 
			
		||||
					noteId: this.note.id
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
<template>
 | 
			
		||||
<div class="tdflqwzn" :class="{ isMe }">
 | 
			
		||||
	<x-reaction v-for="(count, reaction) in note.reactions" :reaction="reaction" :count="count" :is-initial="initialReactions.has(reaction)" :note="note" :key="reaction"/>
 | 
			
		||||
	<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"/>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,16 +12,28 @@ export default Vue.extend({
 | 
			
		|||
	components: {
 | 
			
		||||
		XReaction
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			initialReactions: new Set(Object.keys(this.note.reactions))
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	props: {
 | 
			
		||||
		note: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			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: {
 | 
			
		||||
		isMe(): boolean {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,8 +52,8 @@ export default Vue.extend({
 | 
			
		|||
		});
 | 
			
		||||
 | 
			
		||||
		const prepend = note => {
 | 
			
		||||
			const _note = JSON.parse(JSON.stringify(note));	// deepcopy
 | 
			
		||||
			(this.$refs.tl as any).prepend(_note);
 | 
			
		||||
			Object.freeze(note);
 | 
			
		||||
			(this.$refs.tl as any).prepend(note);
 | 
			
		||||
 | 
			
		||||
			this.$emit('note');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,10 +74,6 @@ export default (opts) => ({
 | 
			
		|||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		updateItem(i, item) {
 | 
			
		||||
			Vue.set((this as any).items, i, item);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		reload() {
 | 
			
		||||
			this.items = [];
 | 
			
		||||
			this.init();
 | 
			
		||||
| 
						 | 
				
			
			@ -94,6 +90,9 @@ export default (opts) => ({
 | 
			
		|||
				...params,
 | 
			
		||||
				limit: this.pagination.noPaging ? (this.pagination.limit || 10) : (this.pagination.limit || 10) + 1,
 | 
			
		||||
			}).then(items => {
 | 
			
		||||
				for (const item of items) {
 | 
			
		||||
					Object.freeze(item);
 | 
			
		||||
				}
 | 
			
		||||
				if (!this.pagination.noPaging && (items.length > (this.pagination.limit || 10))) {
 | 
			
		||||
					items.pop();
 | 
			
		||||
					this.items = this.pagination.reversed ? [...items].reverse() : items;
 | 
			
		||||
| 
						 | 
				
			
			@ -130,6 +129,9 @@ export default (opts) => ({
 | 
			
		|||
					untilId: this.items[this.items.length - 1].id,
 | 
			
		||||
				}),
 | 
			
		||||
			}).then(items => {
 | 
			
		||||
				for (const item of items) {
 | 
			
		||||
					Object.freeze(item);
 | 
			
		||||
				}
 | 
			
		||||
				if (items.length > SECOND_FETCH_LIMIT) {
 | 
			
		||||
					items.pop();
 | 
			
		||||
					this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue