feat: multiple emojis editing
This commit is contained in:
		
							parent
							
								
									b17726c9da
								
							
						
					
					
						commit
						1f2dab0a83
					
				
					 10 changed files with 428 additions and 139 deletions
				
			
		|  | @ -0,0 +1,39 @@ | |||
| import $ from 'cafy'; | ||||
| import define from '../../../define'; | ||||
| import { ID } from '@/misc/cafy-id'; | ||||
| import { Emojis } from '@/models/index'; | ||||
| import { getConnection, In } from 'typeorm'; | ||||
| import { ApiError } from '../../../error'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	tags: ['admin'], | ||||
| 
 | ||||
| 	requireCredential: true as const, | ||||
| 	requireModerator: true, | ||||
| 
 | ||||
| 	params: { | ||||
| 		ids: { | ||||
| 			validator: $.arr($.type(ID)), | ||||
| 		}, | ||||
| 
 | ||||
| 		aliases: { | ||||
| 			validator: $.arr($.str), | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| // eslint-disable-next-line import/no-default-export
 | ||||
| export default define(meta, async (ps) => { | ||||
| 	const emojis = await Emojis.find({ | ||||
| 		id: In(ps.ids), | ||||
| 	}); | ||||
| 
 | ||||
| 	for (const emoji of emojis) { | ||||
| 		await Emojis.update(emoji.id, { | ||||
| 			updatedAt: new Date(), | ||||
| 			aliases: [...new Set(emoji.aliases.concat(ps.aliases))], | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	await getConnection().queryResultCache!.remove(['meta_emojis']); | ||||
| }); | ||||
|  | @ -0,0 +1,37 @@ | |||
| import $ from 'cafy'; | ||||
| import define from '../../../define'; | ||||
| import { ID } from '@/misc/cafy-id'; | ||||
| import { Emojis } from '@/models/index'; | ||||
| import { getConnection, In } from 'typeorm'; | ||||
| import { insertModerationLog } from '@/services/insert-moderation-log'; | ||||
| import { ApiError } from '../../../error'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	tags: ['admin'], | ||||
| 
 | ||||
| 	requireCredential: true as const, | ||||
| 	requireModerator: true, | ||||
| 
 | ||||
| 	params: { | ||||
| 		ids: { | ||||
| 			validator: $.arr($.type(ID)), | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| // eslint-disable-next-line import/no-default-export
 | ||||
| export default define(meta, async (ps, me) => { | ||||
| 	const emojis = await Emojis.find({ | ||||
| 		id: In(ps.ids), | ||||
| 	}); | ||||
| 
 | ||||
| 	for (const emoji of emojis) { | ||||
| 		await Emojis.delete(emoji.id); | ||||
| 	 | ||||
| 		await getConnection().queryResultCache!.remove(['meta_emojis']); | ||||
| 	 | ||||
| 		insertModerationLog(me, 'deleteEmoji', { | ||||
| 			emoji: emoji, | ||||
| 		}); | ||||
| 	} | ||||
| }); | ||||
|  | @ -37,7 +37,7 @@ export default define(meta, async (ps, me) => { | |||
| 
 | ||||
| 	await getConnection().queryResultCache!.remove(['meta_emojis']); | ||||
| 
 | ||||
| 	insertModerationLog(me, 'removeEmoji', { | ||||
| 	insertModerationLog(me, 'deleteEmoji', { | ||||
| 		emoji: emoji, | ||||
| 	}); | ||||
| }); | ||||
|  | @ -0,0 +1,21 @@ | |||
| import $ from 'cafy'; | ||||
| import define from '../../../define'; | ||||
| import { createImportCustomEmojisJob } from '@/queue/index'; | ||||
| import ms from 'ms'; | ||||
| import { ID } from '@/misc/cafy-id'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	secure: true, | ||||
| 	requireCredential: true as const, | ||||
| 	requireModerator: true, | ||||
| 	params: { | ||||
| 		fileId: { | ||||
| 			validator: $.type(ID), | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| // eslint-disable-next-line import/no-default-export
 | ||||
| export default define(meta, async (ps, user) => { | ||||
| 	createImportCustomEmojisJob(user, ps.fileId); | ||||
| }); | ||||
|  | @ -0,0 +1,39 @@ | |||
| import $ from 'cafy'; | ||||
| import define from '../../../define'; | ||||
| import { ID } from '@/misc/cafy-id'; | ||||
| import { Emojis } from '@/models/index'; | ||||
| import { getConnection, In } from 'typeorm'; | ||||
| import { ApiError } from '../../../error'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	tags: ['admin'], | ||||
| 
 | ||||
| 	requireCredential: true as const, | ||||
| 	requireModerator: true, | ||||
| 
 | ||||
| 	params: { | ||||
| 		ids: { | ||||
| 			validator: $.arr($.type(ID)), | ||||
| 		}, | ||||
| 
 | ||||
| 		aliases: { | ||||
| 			validator: $.arr($.str), | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| // eslint-disable-next-line import/no-default-export
 | ||||
| export default define(meta, async (ps) => { | ||||
| 	const emojis = await Emojis.find({ | ||||
| 		id: In(ps.ids), | ||||
| 	}); | ||||
| 
 | ||||
| 	for (const emoji of emojis) { | ||||
| 		await Emojis.update(emoji.id, { | ||||
| 			updatedAt: new Date(), | ||||
| 			aliases: emoji.aliases.filter(x => !ps.aliases.includes(x)), | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	await getConnection().queryResultCache!.remove(['meta_emojis']); | ||||
| }); | ||||
|  | @ -0,0 +1,35 @@ | |||
| import $ from 'cafy'; | ||||
| import define from '../../../define'; | ||||
| import { ID } from '@/misc/cafy-id'; | ||||
| import { Emojis } from '@/models/index'; | ||||
| import { getConnection, In } from 'typeorm'; | ||||
| import { ApiError } from '../../../error'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	tags: ['admin'], | ||||
| 
 | ||||
| 	requireCredential: true as const, | ||||
| 	requireModerator: true, | ||||
| 
 | ||||
| 	params: { | ||||
| 		ids: { | ||||
| 			validator: $.arr($.type(ID)), | ||||
| 		}, | ||||
| 
 | ||||
| 		aliases: { | ||||
| 			validator: $.arr($.str), | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| // eslint-disable-next-line import/no-default-export
 | ||||
| export default define(meta, async (ps) => { | ||||
| 	await Emojis.update({ | ||||
| 		id: In(ps.ids), | ||||
| 	}, { | ||||
| 		updatedAt: new Date(), | ||||
| 		aliases: ps.aliases, | ||||
| 	}); | ||||
| 
 | ||||
| 	await getConnection().queryResultCache!.remove(['meta_emojis']); | ||||
| }); | ||||
|  | @ -0,0 +1,35 @@ | |||
| import $ from 'cafy'; | ||||
| import define from '../../../define'; | ||||
| import { ID } from '@/misc/cafy-id'; | ||||
| import { Emojis } from '@/models/index'; | ||||
| import { getConnection, In } from 'typeorm'; | ||||
| import { ApiError } from '../../../error'; | ||||
| 
 | ||||
| export const meta = { | ||||
| 	tags: ['admin'], | ||||
| 
 | ||||
| 	requireCredential: true as const, | ||||
| 	requireModerator: true, | ||||
| 
 | ||||
| 	params: { | ||||
| 		ids: { | ||||
| 			validator: $.arr($.type(ID)), | ||||
| 		}, | ||||
| 
 | ||||
| 		category: { | ||||
| 			validator: $.optional.nullable.str, | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| // eslint-disable-next-line import/no-default-export
 | ||||
| export default define(meta, async (ps) => { | ||||
| 	await Emojis.update({ | ||||
| 		id: In(ps.ids), | ||||
| 	}, { | ||||
| 		updatedAt: new Date(), | ||||
| 		category: ps.category, | ||||
| 	}); | ||||
| 
 | ||||
| 	await getConnection().queryResultCache!.remove(['meta_emojis']); | ||||
| }); | ||||
|  | @ -95,7 +95,7 @@ export default defineComponent({ | |||
| 			}); | ||||
| 			if (canceled) return; | ||||
| 
 | ||||
| 			os.api('admin/emoji/remove', { | ||||
| 			os.api('admin/emoji/delete', { | ||||
| 				id: this.emoji.id | ||||
| 			}).then(() => { | ||||
| 				this.$emit('done', { | ||||
|  |  | |||
|  | @ -6,11 +6,22 @@ | |||
| 				<template #prefix><i class="fas fa-search"></i></template> | ||||
| 				<template #label>{{ $ts.search }}</template> | ||||
| 			</MkInput> | ||||
| 			<MkPagination ref="emojis" :pagination="pagination"> | ||||
| 			<MkSwitch v-model="selectMode" style="margin: 8px 0;"> | ||||
| 				<template #label>Select mode</template> | ||||
| 			</MkSwitch> | ||||
| 			<div v-if="selectMode" style="display: flex; gap: var(--margin); flex-wrap: wrap;"> | ||||
| 				<MkButton inline @click="selectAll">Select all</MkButton> | ||||
| 				<MkButton inline @click="setCategoryBulk">Set category</MkButton> | ||||
| 				<MkButton inline @click="addTagBulk">Add tag</MkButton> | ||||
| 				<MkButton inline @click="removeTagBulk">Remove tag</MkButton> | ||||
| 				<MkButton inline @click="setTagBulk">Set tag</MkButton> | ||||
| 				<MkButton inline danger @click="delBulk">Delete</MkButton> | ||||
| 			</div> | ||||
| 			<MkPagination ref="emojisPaginationComponent" :pagination="pagination"> | ||||
| 				<template #empty><span>{{ $ts.noCustomEmojis }}</span></template> | ||||
| 				<template v-slot="{items}"> | ||||
| 					<div class="ldhfsamy"> | ||||
| 						<button v-for="emoji in items" :key="emoji.id" class="emoji _panel _button" @click="edit(emoji)"> | ||||
| 						<button v-for="emoji in items" :key="emoji.id" class="emoji _panel _button" :class="{ selected: selectedEmojis.includes(emoji.id) }" @click="selectMode ? toggleSelect(emoji) : edit(emoji)"> | ||||
| 							<img :src="emoji.url" class="img" :alt="emoji.name"/> | ||||
| 							<div class="body"> | ||||
| 								<div class="name _monospace">{{ emoji.name }}</div> | ||||
|  | @ -32,7 +43,7 @@ | |||
| 					<template #label>{{ $ts.host }}</template> | ||||
| 				</MkInput> | ||||
| 			</FormSplit> | ||||
| 			<MkPagination ref="remoteEmojis" :pagination="remotePagination"> | ||||
| 			<MkPagination :pagination="remotePagination"> | ||||
| 				<template #empty><span>{{ $ts.noCustomEmojis }}</span></template> | ||||
| 				<template v-slot="{items}"> | ||||
| 					<div class="ldhfsamy"> | ||||
|  | @ -51,137 +62,118 @@ | |||
| </MkSpacer> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import { computed, defineComponent, toRef } from 'vue'; | ||||
| <script lang="ts" setup> | ||||
| import { computed, defineComponent, ref, toRef } from 'vue'; | ||||
| import MkButton from '@/components/ui/button.vue'; | ||||
| import MkInput from '@/components/form/input.vue'; | ||||
| import MkPagination from '@/components/ui/pagination.vue'; | ||||
| import MkTab from '@/components/tab.vue'; | ||||
| import MkSwitch from '@/components/form/switch.vue'; | ||||
| import FormSplit from '@/components/form/split.vue'; | ||||
| import { selectFiles } from '@/scripts/select-file'; | ||||
| import { selectFile, selectFiles } from '@/scripts/select-file'; | ||||
| import * as os from '@/os'; | ||||
| import * as symbols from '@/symbols'; | ||||
| import { i18n } from '@/i18n'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| 	components: { | ||||
| 		MkTab, | ||||
| 		MkButton, | ||||
| 		MkInput, | ||||
| 		MkPagination, | ||||
| 		FormSplit, | ||||
| 	}, | ||||
| const emojisPaginationComponent = ref<InstanceType<typeof MkPagination>>(); | ||||
| 
 | ||||
| 	emits: ['info'], | ||||
| const tab = ref('local'); | ||||
| const query = ref(null); | ||||
| const queryRemote = ref(null); | ||||
| const host = ref(null); | ||||
| const selectMode = ref(false); | ||||
| const selectedEmojis = ref<string[]>([]); | ||||
| 
 | ||||
| 	data() { | ||||
| 		return { | ||||
| 			[symbols.PAGE_INFO]: computed(() => ({ | ||||
| 				title: this.$ts.customEmojis, | ||||
| 				icon: 'fas fa-laugh', | ||||
| 				bg: 'var(--bg)', | ||||
| 				actions: [{ | ||||
| 					asFullButton: true, | ||||
| 					icon: 'fas fa-plus', | ||||
| 					text: this.$ts.addEmoji, | ||||
| 					handler: this.add, | ||||
| 				}, { | ||||
| 					icon: 'fas fa-ellipsis-h', | ||||
| 					handler: this.menu, | ||||
| 				}], | ||||
| 				tabs: [{ | ||||
| 					active: this.tab === 'local', | ||||
| 					title: this.$ts.local, | ||||
| 					onClick: () => { this.tab = 'local'; }, | ||||
| 				}, { | ||||
| 					active: this.tab === 'remote', | ||||
| 					title: this.$ts.remote, | ||||
| 					onClick: () => { this.tab = 'remote'; }, | ||||
| 				},] | ||||
| 			})), | ||||
| 			tab: 'local', | ||||
| 			query: null, | ||||
| 			queryRemote: null, | ||||
| 			host: '', | ||||
| 			pagination: { | ||||
| const pagination = { | ||||
| 	endpoint: 'admin/emoji/list', | ||||
| 	limit: 30, | ||||
| 	params: computed(() => ({ | ||||
| 					query: (this.query && this.query !== '') ? this.query : null | ||||
| 				})) | ||||
| 			}, | ||||
| 			remotePagination: { | ||||
| 		query: (query.value && query.value !== '') ? query.value : null, | ||||
| 	})), | ||||
| }; | ||||
| 
 | ||||
| const remotePagination = { | ||||
| 	endpoint: 'admin/emoji/list-remote', | ||||
| 	limit: 30, | ||||
| 	params: computed(() => ({ | ||||
| 					query: (this.queryRemote && this.queryRemote !== '') ? this.queryRemote : null, | ||||
| 					host: (this.host && this.host !== '') ? this.host : null | ||||
| 				})) | ||||
| 			}, | ||||
| 		query: (queryRemote.value && queryRemote.value !== '') ? queryRemote.value : null, | ||||
| 		host: (host.value && host.value !== '') ? host.value : null, | ||||
| 	})), | ||||
| }; | ||||
| 
 | ||||
| const selectAll = () => { | ||||
| 	if (selectedEmojis.value.length > 0) { | ||||
| 		selectedEmojis.value = []; | ||||
| 	} else { | ||||
| 		selectedEmojis.value = emojisPaginationComponent.value.items.map(item => item.id); | ||||
| 	} | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| 	async mounted() { | ||||
| 		this.$emit('info', toRef(this, symbols.PAGE_INFO)); | ||||
| 	}, | ||||
| const toggleSelect = (emoji) => { | ||||
| 	if (selectedEmojis.value.includes(emoji.id)) { | ||||
| 		selectedEmojis.value = selectedEmojis.value.filter(x => x !== emoji.id); | ||||
| 	} else { | ||||
| 		selectedEmojis.value.push(emoji.id); | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| 	methods: { | ||||
| 		async add(e) { | ||||
| 			const files = await selectFiles(e.currentTarget || e.target, null); | ||||
| const add = async (ev: MouseEvent) => { | ||||
| 	const files = await selectFiles(ev.currentTarget || ev.target, null); | ||||
| 
 | ||||
| 	const promise = Promise.all(files.map(file => os.api('admin/emoji/add', { | ||||
| 		fileId: file.id, | ||||
| 	}))); | ||||
| 	promise.then(() => { | ||||
| 				this.$refs.emojis.reload(); | ||||
| 		emojisPaginationComponent.value.reload(); | ||||
| 	}); | ||||
| 	os.promiseDialog(promise); | ||||
| 		}, | ||||
| }; | ||||
| 
 | ||||
| 		edit(emoji) { | ||||
| const edit = (emoji) => { | ||||
| 	os.popup(import('./emoji-edit-dialog.vue'), { | ||||
| 		emoji: emoji | ||||
| 	}, { | ||||
| 		done: result => { | ||||
| 			if (result.updated) { | ||||
| 						this.$refs.emojis.replaceItem(item => item.id === emoji.id, { | ||||
| 				emojisPaginationComponent.value.replaceItem(item => item.id === emoji.id, { | ||||
| 					...emoji, | ||||
| 					...result.updated | ||||
| 				}); | ||||
| 			} else if (result.deleted) { | ||||
| 						this.$refs.emojis.removeItem(item => item.id === emoji.id); | ||||
| 				emojisPaginationComponent.value.removeItem(item => item.id === emoji.id); | ||||
| 			} | ||||
| 		}, | ||||
| 	}, 'closed'); | ||||
| 		}, | ||||
| }; | ||||
| 
 | ||||
| 		im(emoji) { | ||||
| const im = (emoji) => { | ||||
| 	os.apiWithDialog('admin/emoji/copy', { | ||||
| 		emojiId: emoji.id, | ||||
| 	}); | ||||
| 		}, | ||||
| }; | ||||
| 
 | ||||
| 		remoteMenu(emoji, ev) { | ||||
| const remoteMenu = (emoji, ev: MouseEvent) => { | ||||
| 	os.popupMenu([{ | ||||
| 		type: 'label', | ||||
| 		text: ':' + emoji.name + ':', | ||||
| 	}, { | ||||
| 				text: this.$ts.import, | ||||
| 		text: i18n.locale.import, | ||||
| 		icon: 'fas fa-plus', | ||||
| 				action: () => { this.im(emoji) } | ||||
| 		action: () => { im(emoji) } | ||||
| 	}], ev.currentTarget || ev.target); | ||||
| 		}, | ||||
| }; | ||||
| 
 | ||||
| 		menu(ev) { | ||||
| const menu = (ev: MouseEvent) => { | ||||
| 	os.popupMenu([{ | ||||
| 		icon: 'fas fa-download', | ||||
| 				text: this.$ts.export, | ||||
| 		text: i18n.locale.export, | ||||
| 		action: async () => { | ||||
| 			os.api('export-custom-emojis', { | ||||
| 			}) | ||||
| 			.then(() => { | ||||
| 				os.alert({ | ||||
| 					type: 'info', | ||||
| 							text: this.$ts.exportRequested, | ||||
| 					text: i18n.locale.exportRequested, | ||||
| 				}); | ||||
| 			}).catch((e) => { | ||||
| 				os.alert({ | ||||
|  | @ -191,8 +183,92 @@ export default defineComponent({ | |||
| 			}); | ||||
| 		} | ||||
| 	}], ev.currentTarget || ev.target); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| const setCategoryBulk = async () => { | ||||
| 	const { canceled, result } = await os.inputText({ | ||||
| 		title: 'Category', | ||||
| 	}); | ||||
| 	if (canceled) return; | ||||
| 	await os.apiWithDialog('admin/emoji/set-category-bulk', { | ||||
| 		ids: selectedEmojis.value, | ||||
| 		category: result, | ||||
| 	}); | ||||
| 	emojisPaginationComponent.value.reload(); | ||||
| }; | ||||
| 
 | ||||
| const addTagBulk = async () => { | ||||
| 	const { canceled, result } = await os.inputText({ | ||||
| 		title: 'Tag', | ||||
| 	}); | ||||
| 	if (canceled) return; | ||||
| 	await os.apiWithDialog('admin/emoji/add-aliases-bulk', { | ||||
| 		ids: selectedEmojis.value, | ||||
| 		aliases: result.split(' '), | ||||
| 	}); | ||||
| 	emojisPaginationComponent.value.reload(); | ||||
| }; | ||||
| 
 | ||||
| const removeTagBulk = async () => { | ||||
| 	const { canceled, result } = await os.inputText({ | ||||
| 		title: 'Tag', | ||||
| 	}); | ||||
| 	if (canceled) return; | ||||
| 	await os.apiWithDialog('admin/emoji/remove-aliases-bulk', { | ||||
| 		ids: selectedEmojis.value, | ||||
| 		aliases: result.split(' '), | ||||
| 	}); | ||||
| 	emojisPaginationComponent.value.reload(); | ||||
| }; | ||||
| 
 | ||||
| const setTagBulk = async () => { | ||||
| 	const { canceled, result } = await os.inputText({ | ||||
| 		title: 'Tag', | ||||
| 	}); | ||||
| 	if (canceled) return; | ||||
| 	await os.apiWithDialog('admin/emoji/set-aliases-bulk', { | ||||
| 		ids: selectedEmojis.value, | ||||
| 		aliases: result.split(' '), | ||||
| 	}); | ||||
| 	emojisPaginationComponent.value.reload(); | ||||
| }; | ||||
| 
 | ||||
| const delBulk = async () => { | ||||
| 	const { canceled } = await os.confirm({ | ||||
| 		type: 'warning', | ||||
| 		text: i18n.locale.deleteConfirm, | ||||
| 	}); | ||||
| 	if (canceled) return; | ||||
| 	await os.apiWithDialog('admin/emoji/delete-bulk', { | ||||
| 		ids: selectedEmojis.value, | ||||
| 	}); | ||||
| 	emojisPaginationComponent.value.reload(); | ||||
| }; | ||||
| 
 | ||||
| defineExpose({ | ||||
| 	[symbols.PAGE_INFO]: computed(() => ({ | ||||
| 		title: i18n.locale.customEmojis, | ||||
| 		icon: 'fas fa-laugh', | ||||
| 		bg: 'var(--bg)', | ||||
| 		actions: [{ | ||||
| 			asFullButton: true, | ||||
| 			icon: 'fas fa-plus', | ||||
| 			text: i18n.locale.addEmoji, | ||||
| 			handler: add, | ||||
| 		}, { | ||||
| 			icon: 'fas fa-ellipsis-h', | ||||
| 			handler: menu, | ||||
| 		}], | ||||
| 		tabs: [{ | ||||
| 			active: tab.value === 'local', | ||||
| 			title: i18n.locale.local, | ||||
| 			onClick: () => { tab.value = 'local'; }, | ||||
| 		}, { | ||||
| 			active: tab.value === 'remote', | ||||
| 			title: i18n.locale.remote, | ||||
| 			onClick: () => { tab.value = 'remote'; }, | ||||
| 		},] | ||||
| 	})), | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
|  | @ -212,11 +288,16 @@ export default defineComponent({ | |||
| 			> .emoji { | ||||
| 				display: flex; | ||||
| 				align-items: center; | ||||
| 				padding: 12px; | ||||
| 				padding: 11px; | ||||
| 				text-align: left; | ||||
| 				border: solid 1px var(--panel); | ||||
| 
 | ||||
| 				&:hover { | ||||
| 					color: var(--accent); | ||||
| 					border-color: var(--inputBorderHover); | ||||
| 				} | ||||
| 
 | ||||
| 				&.selected { | ||||
| 					border-color: var(--accent); | ||||
| 				} | ||||
| 
 | ||||
| 				> .img { | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ | |||
| 	<div class="main"> | ||||
| 		<MkStickyContainer> | ||||
| 			<template #header><MkHeader v-if="childInfo && !childInfo.hideHeader" :info="childInfo"/></template> | ||||
| 			<component :is="component" :key="page" v-bind="pageProps" @info="onInfo"/> | ||||
| 			<component :is="component" :ref="el => pageChanged(el)" :key="page" v-bind="pageProps"/> | ||||
| 		</MkStickyContainer> | ||||
| 	</div> | ||||
| </div> | ||||
|  | @ -66,7 +66,9 @@ export default defineComponent({ | |||
| 		const narrow = ref(false); | ||||
| 		const view = ref(null); | ||||
| 		const el = ref(null); | ||||
| 		const onInfo = (viewInfo) => { | ||||
| 		const pageChanged = (page) => { | ||||
| 			if (page == null) return; | ||||
| 			const viewInfo = page[symbols.PAGE_INFO]; | ||||
| 			if (isRef(viewInfo)) { | ||||
| 				watch(viewInfo, () => { | ||||
| 					childInfo.value = viewInfo.value; | ||||
|  | @ -311,7 +313,7 @@ export default defineComponent({ | |||
| 			narrow, | ||||
| 			view, | ||||
| 			el, | ||||
| 			onInfo, | ||||
| 			pageChanged, | ||||
| 			childInfo, | ||||
| 			pageProps, | ||||
| 			component, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue