mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/455 Approved-by: fEmber <acomputerdog@gmail.com> Approved-by: Leah <kevinlukej@gmail.com> Approved-by: Amelia Yukii <amelia.yukii@shourai.de>
This commit is contained in:
		
						commit
						a9b1affdf0
					
				
					 7 changed files with 144 additions and 10 deletions
				
			
		| 
						 | 
					@ -51,6 +51,12 @@ export const paramDef = {
 | 
				
			||||||
		sinceDate: { type: 'integer' },
 | 
							sinceDate: { type: 'integer' },
 | 
				
			||||||
		untilDate: { type: 'integer' },
 | 
							untilDate: { type: 'integer' },
 | 
				
			||||||
		allowPartial: { type: 'boolean', default: false }, // true is recommended but for compatibility false by default
 | 
							allowPartial: { type: 'boolean', default: false }, // true is recommended but for compatibility false by default
 | 
				
			||||||
 | 
							withRenotes: { type: 'boolean', default: true },
 | 
				
			||||||
 | 
							withFiles: {
 | 
				
			||||||
 | 
								type: 'boolean',
 | 
				
			||||||
 | 
								default: false,
 | 
				
			||||||
 | 
								description: 'Only show notes that have attached files.',
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	required: ['channelId'],
 | 
						required: ['channelId'],
 | 
				
			||||||
} as const;
 | 
					} as const;
 | 
				
			||||||
| 
						 | 
					@ -89,7 +95,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
				
			||||||
			if (me) this.activeUsersChart.read(me);
 | 
								if (me) this.activeUsersChart.read(me);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!serverSettings.enableFanoutTimeline) {
 | 
								if (!serverSettings.enableFanoutTimeline) {
 | 
				
			||||||
				return await this.noteEntityService.packMany(await this.getFromDb({ untilId, sinceId, limit: ps.limit, channelId: channel.id }, me), me);
 | 
									return await this.noteEntityService.packMany(await this.getFromDb({ untilId, sinceId, limit: ps.limit, channelId: channel.id, withFiles: ps.withFiles, withRenotes: ps.withRenotes }, me), me);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return await this.fanoutTimelineEndpointService.timeline({
 | 
								return await this.fanoutTimelineEndpointService.timeline({
 | 
				
			||||||
| 
						 | 
					@ -100,9 +106,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
				
			||||||
				me,
 | 
									me,
 | 
				
			||||||
				useDbFallback: true,
 | 
									useDbFallback: true,
 | 
				
			||||||
				redisTimelines: [`channelTimeline:${channel.id}`],
 | 
									redisTimelines: [`channelTimeline:${channel.id}`],
 | 
				
			||||||
				excludePureRenotes: false,
 | 
									excludePureRenotes: !ps.withRenotes,
 | 
				
			||||||
 | 
									excludeNoFiles: ps.withFiles,
 | 
				
			||||||
				dbFallback: async (untilId, sinceId, limit) => {
 | 
									dbFallback: async (untilId, sinceId, limit) => {
 | 
				
			||||||
					return await this.getFromDb({ untilId, sinceId, limit, channelId: channel.id }, me);
 | 
										return await this.getFromDb({ untilId, sinceId, limit, channelId: channel.id, withFiles: ps.withFiles, withRenotes: ps.withRenotes }, me);
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
| 
						 | 
					@ -112,7 +119,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
				
			||||||
		untilId: string | null,
 | 
							untilId: string | null,
 | 
				
			||||||
		sinceId: string | null,
 | 
							sinceId: string | null,
 | 
				
			||||||
		limit: number,
 | 
							limit: number,
 | 
				
			||||||
		channelId: string
 | 
							channelId: string,
 | 
				
			||||||
 | 
							withFiles: boolean,
 | 
				
			||||||
 | 
							withRenotes: boolean,
 | 
				
			||||||
	}, me: MiLocalUser | null) {
 | 
						}, me: MiLocalUser | null) {
 | 
				
			||||||
		//#region fallback to database
 | 
							//#region fallback to database
 | 
				
			||||||
		const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 | 
							const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), ps.sinceId, ps.untilId)
 | 
				
			||||||
| 
						 | 
					@ -128,6 +137,20 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 | 
				
			||||||
			this.queryService.generateMutedUserQuery(query, me);
 | 
								this.queryService.generateMutedUserQuery(query, me);
 | 
				
			||||||
			this.queryService.generateBlockedUserQuery(query, me);
 | 
								this.queryService.generateBlockedUserQuery(query, me);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ps.withRenotes === false) {
 | 
				
			||||||
 | 
								query.andWhere(new Brackets(qb => {
 | 
				
			||||||
 | 
									qb.orWhere('note.renoteId IS NULL');
 | 
				
			||||||
 | 
									qb.orWhere(new Brackets(qb => {
 | 
				
			||||||
 | 
										qb.orWhere('note.text IS NOT NULL');
 | 
				
			||||||
 | 
										qb.orWhere('note.fileIds != \'{}\'');
 | 
				
			||||||
 | 
									}));
 | 
				
			||||||
 | 
								}));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ps.withFiles) {
 | 
				
			||||||
 | 
								query.andWhere('note.fileIds != \'{}\'');
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		//#endregion
 | 
							//#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return await query.limit(ps.limit).getMany();
 | 
							return await query.limit(ps.limit).getMany();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,8 @@ class ChannelChannel extends Channel {
 | 
				
			||||||
	public static shouldShare = false;
 | 
						public static shouldShare = false;
 | 
				
			||||||
	public static requireCredential = false as const;
 | 
						public static requireCredential = false as const;
 | 
				
			||||||
	private channelId: string;
 | 
						private channelId: string;
 | 
				
			||||||
 | 
						private withFiles: boolean;
 | 
				
			||||||
 | 
						private withRenotes: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constructor(
 | 
						constructor(
 | 
				
			||||||
		private noteEntityService: NoteEntityService,
 | 
							private noteEntityService: NoteEntityService,
 | 
				
			||||||
| 
						 | 
					@ -29,6 +31,8 @@ class ChannelChannel extends Channel {
 | 
				
			||||||
	@bindThis
 | 
						@bindThis
 | 
				
			||||||
	public async init(params: any) {
 | 
						public async init(params: any) {
 | 
				
			||||||
		this.channelId = params.channelId as string;
 | 
							this.channelId = params.channelId as string;
 | 
				
			||||||
 | 
							this.withFiles = params.withFiles ?? false;
 | 
				
			||||||
 | 
							this.withRenotes = params.withRenotes ?? true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Subscribe stream
 | 
							// Subscribe stream
 | 
				
			||||||
		this.subscriber.on('notesStream', this.onNote);
 | 
							this.subscriber.on('notesStream', this.onNote);
 | 
				
			||||||
| 
						 | 
					@ -38,6 +42,10 @@ class ChannelChannel extends Channel {
 | 
				
			||||||
	private async onNote(note: Packed<'Note'>) {
 | 
						private async onNote(note: Packed<'Note'>) {
 | 
				
			||||||
		if (note.channelId !== this.channelId) return;
 | 
							if (note.channelId !== this.channelId) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this.withFiles && (note.fileIds == null || note.fileIds.length === 0)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
 | 
							// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
 | 
				
			||||||
		if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 | 
							if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 | 
				
			||||||
		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
 | 
							// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -154,6 +154,8 @@ function connectChannel() {
 | 
				
			||||||
	} else if (props.src === 'channel') {
 | 
						} else if (props.src === 'channel') {
 | 
				
			||||||
		if (props.channel == null) return;
 | 
							if (props.channel == null) return;
 | 
				
			||||||
		connection = stream.useChannel('channel', {
 | 
							connection = stream.useChannel('channel', {
 | 
				
			||||||
 | 
								withRenotes: props.withRenotes,
 | 
				
			||||||
 | 
								withFiles: props.onlyFiles ? true : undefined,
 | 
				
			||||||
			channelId: props.channel,
 | 
								channelId: props.channel,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	} else if (props.src === 'role') {
 | 
						} else if (props.src === 'role') {
 | 
				
			||||||
| 
						 | 
					@ -234,6 +236,8 @@ function updatePaginationQuery() {
 | 
				
			||||||
	} else if (props.src === 'channel') {
 | 
						} else if (props.src === 'channel') {
 | 
				
			||||||
		endpoint = 'channels/timeline';
 | 
							endpoint = 'channels/timeline';
 | 
				
			||||||
		query = {
 | 
							query = {
 | 
				
			||||||
 | 
								withRenotes: props.withRenotes,
 | 
				
			||||||
 | 
								withFiles: props.onlyFiles ? true : undefined,
 | 
				
			||||||
			channelId: props.channel,
 | 
								channelId: props.channel,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	} else if (props.src === 'role') {
 | 
						} else if (props.src === 'role') {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
				<!-- スマホ・タブレットの場合、キーボードが表示されると投稿が見づらくなるので、デスクトップ場合のみ自動でフォーカスを当てる -->
 | 
									<!-- スマホ・タブレットの場合、キーボードが表示されると投稿が見づらくなるので、デスクトップ場合のみ自動でフォーカスを当てる -->
 | 
				
			||||||
				<MkPostForm v-if="$i && defaultStore.reactiveState.showFixedPostFormInChannel.value" :channel="channel" class="post-form _panel" fixed :autofocus="deviceKind === 'desktop'"/>
 | 
									<MkPostForm v-if="$i && defaultStore.reactiveState.showFixedPostFormInChannel.value" :channel="channel" class="post-form _panel" fixed :autofocus="deviceKind === 'desktop'"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<MkTimeline :key="channelId" src="channel" :channel="channelId" @before="before" @after="after" @note="miLocalStorage.setItemAsJson(`channelLastReadedAt:${channel.id}`, Date.now())"/>
 | 
									<MkTimeline :key="channelId + withRenotes + onlyFiles" src="channel" :channel="channelId" :withRenotes="withRenotes" :onlyFiles="onlyFiles" @before="before" @after="after" @note="miLocalStorage.setItemAsJson(`channelLastReadedAt:${channel.id}`, Date.now())"/>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
			<div v-else-if="tab === 'featured'" key="featured">
 | 
								<div v-else-if="tab === 'featured'" key="featured">
 | 
				
			||||||
				<MkNotes :pagination="featuredPagination"/>
 | 
									<MkNotes :pagination="featuredPagination"/>
 | 
				
			||||||
| 
						 | 
					@ -95,6 +95,7 @@ import { isSupportShare } from '@/scripts/navigator.js';
 | 
				
			||||||
import copyToClipboard from '@/scripts/copy-to-clipboard.js';
 | 
					import copyToClipboard from '@/scripts/copy-to-clipboard.js';
 | 
				
			||||||
import { miLocalStorage } from '@/local-storage.js';
 | 
					import { miLocalStorage } from '@/local-storage.js';
 | 
				
			||||||
import { useRouter } from '@/router/supplier.js';
 | 
					import { useRouter } from '@/router/supplier.js';
 | 
				
			||||||
 | 
					import { deepMerge } from '@/scripts/merge.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = useRouter();
 | 
					const router = useRouter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,6 +117,15 @@ const featuredPagination = computed(() => ({
 | 
				
			||||||
		channelId: props.channelId,
 | 
							channelId: props.channelId,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					const withRenotes = computed<boolean>({
 | 
				
			||||||
 | 
						get: () => defaultStore.reactiveState.tl.value.filter.withRenotes,
 | 
				
			||||||
 | 
						set: (x) => saveTlFilter('withRenotes', x),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const onlyFiles = computed<boolean>({
 | 
				
			||||||
 | 
						get: () => defaultStore.reactiveState.tl.value.filter.onlyFiles,
 | 
				
			||||||
 | 
						set: (x) => saveTlFilter('onlyFiles', x),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
watch(() => props.channelId, async () => {
 | 
					watch(() => props.channelId, async () => {
 | 
				
			||||||
	channel.value = await misskeyApi('channels/show', {
 | 
						channel.value = await misskeyApi('channels/show', {
 | 
				
			||||||
| 
						 | 
					@ -136,6 +146,13 @@ watch(() => props.channelId, async () => {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}, { immediate: true });
 | 
					}, { immediate: true });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function saveTlFilter(key: keyof typeof defaultStore.state.tl.filter, newValue: boolean) {
 | 
				
			||||||
 | 
						if (key !== 'withReplies' || $i) {
 | 
				
			||||||
 | 
							const out = deepMerge({ filter: { [key]: newValue } }, defaultStore.state.tl);
 | 
				
			||||||
 | 
							defaultStore.set('tl', out);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function edit() {
 | 
					function edit() {
 | 
				
			||||||
	router.push(`/channels/${channel.value?.id}/edit`);
 | 
						router.push(`/channels/${channel.value?.id}/edit`);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -192,7 +209,21 @@ async function search() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const headerActions = computed(() => {
 | 
					const headerActions = computed(() => {
 | 
				
			||||||
	if (channel.value && channel.value.userId) {
 | 
						if (channel.value && channel.value.userId) {
 | 
				
			||||||
		const headerItems: PageHeaderItem[] = [];
 | 
							const headerItems: PageHeaderItem[] = [{
 | 
				
			||||||
 | 
								icon: 'ph-dots-three ph-bold ph-lg',
 | 
				
			||||||
 | 
								text: i18n.ts.options,
 | 
				
			||||||
 | 
								handler: (ev) => {
 | 
				
			||||||
 | 
									os.popupMenu([{
 | 
				
			||||||
 | 
										type: 'switch',
 | 
				
			||||||
 | 
										text: i18n.ts.showRenotes,
 | 
				
			||||||
 | 
										ref: withRenotes,
 | 
				
			||||||
 | 
									}, {
 | 
				
			||||||
 | 
										type: 'switch',
 | 
				
			||||||
 | 
										text: i18n.ts.fileAttachedOnly,
 | 
				
			||||||
 | 
										ref: onlyFiles,
 | 
				
			||||||
 | 
									}], ev.currentTarget ?? ev.target);
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		headerItems.push({
 | 
							headerItems.push({
 | 
				
			||||||
			icon: 'ph-share-network ph-bold ph-lg',
 | 
								icon: 'ph-share-network ph-bold ph-lg',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,10 +11,12 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
			<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
 | 
								<div v-if="queue > 0" :class="$style.new"><button class="_buttonPrimary" :class="$style.newButton" @click="top()">{{ i18n.ts.newNoteRecived }}</button></div>
 | 
				
			||||||
			<div :class="$style.tl">
 | 
								<div :class="$style.tl">
 | 
				
			||||||
				<MkTimeline
 | 
									<MkTimeline
 | 
				
			||||||
					ref="tlEl" :key="listId"
 | 
										ref="tlEl" :key="listId + withRenotes + onlyFiles"
 | 
				
			||||||
					src="list"
 | 
										src="list"
 | 
				
			||||||
					:list="listId"
 | 
										:list="listId"
 | 
				
			||||||
					:sound="true"
 | 
										:sound="true"
 | 
				
			||||||
 | 
										:withRenotes="withRenotes"
 | 
				
			||||||
 | 
										:onlyFiles="onlyFiles"
 | 
				
			||||||
					@queue="queueUpdated"
 | 
										@queue="queueUpdated"
 | 
				
			||||||
				/>
 | 
									/>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
| 
						 | 
					@ -32,6 +34,9 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
 | 
				
			||||||
import { definePageMetadata } from '@/scripts/page-metadata.js';
 | 
					import { definePageMetadata } from '@/scripts/page-metadata.js';
 | 
				
			||||||
import { i18n } from '@/i18n.js';
 | 
					import { i18n } from '@/i18n.js';
 | 
				
			||||||
import { useRouter } from '@/router/supplier.js';
 | 
					import { useRouter } from '@/router/supplier.js';
 | 
				
			||||||
 | 
					import { defaultStore } from '@/store.js';
 | 
				
			||||||
 | 
					import { deepMerge } from '@/scripts/merge.js';
 | 
				
			||||||
 | 
					import * as os from '@/os.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const router = useRouter();
 | 
					const router = useRouter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,6 +48,21 @@ const list = ref<Misskey.entities.UserList | null>(null);
 | 
				
			||||||
const queue = ref(0);
 | 
					const queue = ref(0);
 | 
				
			||||||
const tlEl = shallowRef<InstanceType<typeof MkTimeline>>();
 | 
					const tlEl = shallowRef<InstanceType<typeof MkTimeline>>();
 | 
				
			||||||
const rootEl = shallowRef<HTMLElement>();
 | 
					const rootEl = shallowRef<HTMLElement>();
 | 
				
			||||||
 | 
					const withRenotes = computed<boolean>({
 | 
				
			||||||
 | 
						get: () => defaultStore.reactiveState.tl.value.filter.withRenotes,
 | 
				
			||||||
 | 
						set: (x) => saveTlFilter('withRenotes', x),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					const onlyFiles = computed<boolean>({
 | 
				
			||||||
 | 
						get: () => defaultStore.reactiveState.tl.value.filter.onlyFiles,
 | 
				
			||||||
 | 
						set: (x) => saveTlFilter('onlyFiles', x),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function saveTlFilter(key: keyof typeof defaultStore.state.tl.filter, newValue: boolean) {
 | 
				
			||||||
 | 
						if (key !== 'withReplies' || $i) {
 | 
				
			||||||
 | 
							const out = deepMerge({ filter: { [key]: newValue } }, defaultStore.state.tl);
 | 
				
			||||||
 | 
							defaultStore.set('tl', out);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
watch(() => props.listId, async () => {
 | 
					watch(() => props.listId, async () => {
 | 
				
			||||||
	list.value = await misskeyApi('users/lists/show', {
 | 
						list.value = await misskeyApi('users/lists/show', {
 | 
				
			||||||
| 
						 | 
					@ -63,6 +83,20 @@ function settings() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const headerActions = computed(() => list.value ? [{
 | 
					const headerActions = computed(() => list.value ? [{
 | 
				
			||||||
 | 
						icon: 'ph-dots-three ph-bold ph-lg',
 | 
				
			||||||
 | 
						text: i18n.ts.options,
 | 
				
			||||||
 | 
						handler: (ev) => {
 | 
				
			||||||
 | 
							os.popupMenu([{
 | 
				
			||||||
 | 
								type: 'switch',
 | 
				
			||||||
 | 
								text: i18n.ts.showRenotes,
 | 
				
			||||||
 | 
								ref: withRenotes,
 | 
				
			||||||
 | 
							}, {
 | 
				
			||||||
 | 
								type: 'switch',
 | 
				
			||||||
 | 
								text: i18n.ts.fileAttachedOnly,
 | 
				
			||||||
 | 
								ref: onlyFiles,
 | 
				
			||||||
 | 
							}], ev.currentTarget ?? ev.target);
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
	icon: 'ph-gear ph-bold ph-lg',
 | 
						icon: 'ph-gear ph-bold ph-lg',
 | 
				
			||||||
	text: i18n.ts.settings,
 | 
						text: i18n.ts.settings,
 | 
				
			||||||
	handler: settings,
 | 
						handler: settings,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,13 +13,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
		<div style="padding: 8px; text-align: center;">
 | 
							<div style="padding: 8px; text-align: center;">
 | 
				
			||||||
			<MkButton primary gradate rounded inline small @click="post"><i class="ph-pencil-simple ph-bold ph-lg"></i></MkButton>
 | 
								<MkButton primary gradate rounded inline small @click="post"><i class="ph-pencil-simple ph-bold ph-lg"></i></MkButton>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<MkTimeline ref="timeline" src="channel" :channel="column.channelId"/>
 | 
							<MkTimeline ref="timeline" src="channel" :channel="column.channelId" :key="column.channelId + column.withRenotes + column.onlyFiles" :withRenotes="withRenotes" :onlyFiles="onlyFiles"/>
 | 
				
			||||||
	</template>
 | 
						</template>
 | 
				
			||||||
</XColumn>
 | 
					</XColumn>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { shallowRef } from 'vue';
 | 
					import { watch, ref, shallowRef } from 'vue';
 | 
				
			||||||
import * as Misskey from 'misskey-js';
 | 
					import * as Misskey from 'misskey-js';
 | 
				
			||||||
import XColumn from './column.vue';
 | 
					import XColumn from './column.vue';
 | 
				
			||||||
import { updateColumn, Column } from './deck-store.js';
 | 
					import { updateColumn, Column } from './deck-store.js';
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,20 @@ const props = defineProps<{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const timeline = shallowRef<InstanceType<typeof MkTimeline>>();
 | 
					const timeline = shallowRef<InstanceType<typeof MkTimeline>>();
 | 
				
			||||||
const channel = shallowRef<Misskey.entities.Channel>();
 | 
					const channel = shallowRef<Misskey.entities.Channel>();
 | 
				
			||||||
 | 
					const withRenotes = ref(props.column.withRenotes ?? true);
 | 
				
			||||||
 | 
					const onlyFiles = ref(props.column.onlyFiles ?? false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(withRenotes, v => {
 | 
				
			||||||
 | 
						updateColumn(props.column.id, {
 | 
				
			||||||
 | 
							withRenotes: v,
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(onlyFiles, v => {
 | 
				
			||||||
 | 
						updateColumn(props.column.id, {
 | 
				
			||||||
 | 
							onlyFiles: v,
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (props.column.channelId == null) {
 | 
					if (props.column.channelId == null) {
 | 
				
			||||||
	setChannel();
 | 
						setChannel();
 | 
				
			||||||
| 
						 | 
					@ -75,5 +89,13 @@ const menu = [{
 | 
				
			||||||
	icon: 'ph-pencil-simple ph-bold ph-lg',
 | 
						icon: 'ph-pencil-simple ph-bold ph-lg',
 | 
				
			||||||
	text: i18n.ts.selectChannel,
 | 
						text: i18n.ts.selectChannel,
 | 
				
			||||||
	action: setChannel,
 | 
						action: setChannel,
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
						type: 'switch',
 | 
				
			||||||
 | 
						text: i18n.ts.showRenotes,
 | 
				
			||||||
 | 
						ref: withRenotes,
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
						type: 'switch',
 | 
				
			||||||
 | 
						text: i18n.ts.fileAttachedOnly,
 | 
				
			||||||
 | 
						ref: onlyFiles,
 | 
				
			||||||
}];
 | 
					}];
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
		<i class="ph-list ph-bold ph-lg"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 | 
							<i class="ph-list ph-bold ph-lg"></i><span style="margin-left: 8px;">{{ column.name }}</span>
 | 
				
			||||||
	</template>
 | 
						</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<MkTimeline v-if="column.listId" ref="timeline" src="list" :list="column.listId" :withRenotes="withRenotes"/>
 | 
						<MkTimeline v-if="column.listId" ref="timeline" src="list" :list="column.listId" :key="column.listId + column.withRenotes + column.onlyFiles" :withRenotes="withRenotes" :onlyFiles="onlyFiles"/>
 | 
				
			||||||
</XColumn>
 | 
					</XColumn>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@ const props = defineProps<{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const timeline = shallowRef<InstanceType<typeof MkTimeline>>();
 | 
					const timeline = shallowRef<InstanceType<typeof MkTimeline>>();
 | 
				
			||||||
const withRenotes = ref(props.column.withRenotes ?? true);
 | 
					const withRenotes = ref(props.column.withRenotes ?? true);
 | 
				
			||||||
 | 
					const onlyFiles = ref(props.column.onlyFiles ?? false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (props.column.listId == null) {
 | 
					if (props.column.listId == null) {
 | 
				
			||||||
	setList();
 | 
						setList();
 | 
				
			||||||
| 
						 | 
					@ -40,6 +41,12 @@ watch(withRenotes, v => {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(onlyFiles, v => {
 | 
				
			||||||
 | 
						updateColumn(props.column.id, {
 | 
				
			||||||
 | 
							onlyFiles: v,
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function setList() {
 | 
					async function setList() {
 | 
				
			||||||
	const lists = await misskeyApi('users/lists/list');
 | 
						const lists = await misskeyApi('users/lists/list');
 | 
				
			||||||
	const { canceled, result: list } = await os.select({
 | 
						const { canceled, result: list } = await os.select({
 | 
				
			||||||
| 
						 | 
					@ -75,5 +82,10 @@ const menu = [
 | 
				
			||||||
		text: i18n.ts.showRenotes,
 | 
							text: i18n.ts.showRenotes,
 | 
				
			||||||
		ref: withRenotes,
 | 
							ref: withRenotes,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							type: 'switch',
 | 
				
			||||||
 | 
							text: i18n.ts.fileAttachedOnly,
 | 
				
			||||||
 | 
							ref: onlyFiles,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue