parent
							
								
									1a698111a4
								
							
						
					
					
						commit
						0f1c0a42a2
					
				
					 15 changed files with 190 additions and 300 deletions
				
			
		|  | @ -857,6 +857,7 @@ check: "チェック" | |||
| isSystemAccount: "システムにより自動で作成・管理されているアカウントです。" | ||||
| typeToConfirm: "この操作を行うには {x} と入力してください" | ||||
| deleteAccount: "アカウント削除" | ||||
| document: "ドキュメント" | ||||
| 
 | ||||
| _emailUnavailable: | ||||
|   used: "既に使用されています" | ||||
|  |  | |||
|  | @ -16,13 +16,13 @@ | |||
| 			</template> | ||||
| 		</div> | ||||
| 		<div class="sub"> | ||||
| 			<a v-click-anime href="https://misskey-hub.net/help.html" target="_blank" @click.passive="close()"> | ||||
| 			<button v-click-anime class="_button" @click="help"> | ||||
| 				<i class="fas fa-question-circle icon"></i> | ||||
| 				<div class="text">{{ $ts.help }}</div> | ||||
| 			</a> | ||||
| 			</button> | ||||
| 			<MkA v-click-anime to="/about" @click.passive="close()"> | ||||
| 				<i class="fas fa-info-circle icon"></i> | ||||
| 				<div class="text">{{ $t('aboutX', { x: instanceName }) }}</div> | ||||
| 				<div class="text">{{ $ts.instanceInfo }}</div> | ||||
| 			</MkA> | ||||
| 			<MkA v-click-anime to="/about-misskey" @click.passive="close()"> | ||||
| 				<img src="/static-assets/favicon.png" class="icon"/> | ||||
|  | @ -34,13 +34,14 @@ | |||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import {  } from 'vue'; | ||||
| import { } from 'vue'; | ||||
| import MkModal from '@/components/ui/modal.vue'; | ||||
| import { menuDef } from '@/menu'; | ||||
| import { instanceName } from '@/config'; | ||||
| import { defaultStore } from '@/store'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { deviceKind } from '@/scripts/device-kind'; | ||||
| import * as os from '@/os'; | ||||
| 
 | ||||
| const props = withDefaults(defineProps<{ | ||||
| 	src?: HTMLElement; | ||||
|  | @ -73,6 +74,28 @@ const items = Object.keys(menuDef).filter(k => !menu.includes(k)).map(k => menuD | |||
| function close() { | ||||
| 	modal.close(); | ||||
| } | ||||
| 
 | ||||
| function help(ev: MouseEvent) { | ||||
| 	os.popupMenu([{ | ||||
| 		type: 'link', | ||||
| 		to: '/mfm-cheat-sheet', | ||||
| 		text: i18n.ts._mfm.cheatSheet, | ||||
| 		icon: 'fas fa-code', | ||||
| 	}, { | ||||
| 		type: 'link', | ||||
| 		to: '/scratchpad', | ||||
| 		text: i18n.ts.scratchpad, | ||||
| 		icon: 'fas fa-terminal', | ||||
| 	}, null, { | ||||
| 		text: i18n.ts.document, | ||||
| 		icon: 'fas fa-question-circle', | ||||
| 		action: () => { | ||||
| 			window.open('https://misskey-hub.net/help.html', '_blank'); | ||||
| 		}, | ||||
| 	}], ev.currentTarget ?? ev.target); | ||||
| 
 | ||||
| 	close(); | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
|  |  | |||
|  | @ -112,20 +112,6 @@ export const menuDef = reactive({ | |||
| 			os.popupMenu(items, ev.currentTarget ?? ev.target); | ||||
| 		}, | ||||
| 	}, | ||||
| 	mentions: { | ||||
| 		title: 'mentions', | ||||
| 		icon: 'fas fa-at', | ||||
| 		show: computed(() => $i != null), | ||||
| 		indicated: computed(() => $i != null && $i.hasUnreadMentions), | ||||
| 		to: '/my/mentions', | ||||
| 	}, | ||||
| 	messages: { | ||||
| 		title: 'directNotes', | ||||
| 		icon: 'fas fa-envelope', | ||||
| 		show: computed(() => $i != null), | ||||
| 		indicated: computed(() => $i != null && $i.hasUnreadSpecifiedNotes), | ||||
| 		to: '/my/messages', | ||||
| 	}, | ||||
| 	favorites: { | ||||
| 		title: 'favorites', | ||||
| 		icon: 'fas fa-star', | ||||
|  | @ -153,21 +139,6 @@ export const menuDef = reactive({ | |||
| 		icon: 'fas fa-satellite-dish', | ||||
| 		to: '/channels', | ||||
| 	}, | ||||
| 	federation: { | ||||
| 		title: 'federation', | ||||
| 		icon: 'fas fa-globe', | ||||
| 		to: '/federation', | ||||
| 	}, | ||||
| 	emojis: { | ||||
| 		title: 'emojis', | ||||
| 		icon: 'fas fa-laugh', | ||||
| 		to: '/emojis', | ||||
| 	}, | ||||
| 	scratchpad: { | ||||
| 		title: 'scratchpad', | ||||
| 		icon: 'fas fa-terminal', | ||||
| 		to: '/scratchpad', | ||||
| 	}, | ||||
| 	ui: { | ||||
| 		title: 'switchUi', | ||||
| 		icon: 'fas fa-columns', | ||||
|  |  | |||
							
								
								
									
										106
									
								
								packages/client/src/pages/about.federation.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								packages/client/src/pages/about.federation.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,106 @@ | |||
| <template> | ||||
| <div class="taeiyria"> | ||||
| 	<div class="query"> | ||||
| 		<MkInput v-model="host" :debounce="true" class=""> | ||||
| 			<template #prefix><i class="fas fa-search"></i></template> | ||||
| 			<template #label>{{ $ts.host }}</template> | ||||
| 		</MkInput> | ||||
| 		<FormSplit style="margin-top: var(--margin);"> | ||||
| 			<MkSelect v-model="state"> | ||||
| 				<template #label>{{ $ts.state }}</template> | ||||
| 				<option value="all">{{ $ts.all }}</option> | ||||
| 				<option value="federating">{{ $ts.federating }}</option> | ||||
| 				<option value="subscribing">{{ $ts.subscribing }}</option> | ||||
| 				<option value="publishing">{{ $ts.publishing }}</option> | ||||
| 				<option value="suspended">{{ $ts.suspended }}</option> | ||||
| 				<option value="blocked">{{ $ts.blocked }}</option> | ||||
| 				<option value="notResponding">{{ $ts.notResponding }}</option> | ||||
| 			</MkSelect> | ||||
| 			<MkSelect v-model="sort"> | ||||
| 				<template #label>{{ $ts.sort }}</template> | ||||
| 				<option value="+pubSub">{{ $ts.pubSub }} ({{ $ts.descendingOrder }})</option> | ||||
| 				<option value="-pubSub">{{ $ts.pubSub }} ({{ $ts.ascendingOrder }})</option> | ||||
| 				<option value="+notes">{{ $ts.notes }} ({{ $ts.descendingOrder }})</option> | ||||
| 				<option value="-notes">{{ $ts.notes }} ({{ $ts.ascendingOrder }})</option> | ||||
| 				<option value="+users">{{ $ts.users }} ({{ $ts.descendingOrder }})</option> | ||||
| 				<option value="-users">{{ $ts.users }} ({{ $ts.ascendingOrder }})</option> | ||||
| 				<option value="+following">{{ $ts.following }} ({{ $ts.descendingOrder }})</option> | ||||
| 				<option value="-following">{{ $ts.following }} ({{ $ts.ascendingOrder }})</option> | ||||
| 				<option value="+followers">{{ $ts.followers }} ({{ $ts.descendingOrder }})</option> | ||||
| 				<option value="-followers">{{ $ts.followers }} ({{ $ts.ascendingOrder }})</option> | ||||
| 				<option value="+caughtAt">{{ $ts.registeredAt }} ({{ $ts.descendingOrder }})</option> | ||||
| 				<option value="-caughtAt">{{ $ts.registeredAt }} ({{ $ts.ascendingOrder }})</option> | ||||
| 				<option value="+lastCommunicatedAt">{{ $ts.lastCommunication }} ({{ $ts.descendingOrder }})</option> | ||||
| 				<option value="-lastCommunicatedAt">{{ $ts.lastCommunication }} ({{ $ts.ascendingOrder }})</option> | ||||
| 			</MkSelect> | ||||
| 		</FormSplit> | ||||
| 	</div> | ||||
| 
 | ||||
| 	<MkPagination v-slot="{items}" ref="instances" :key="host + state" :pagination="pagination"> | ||||
| 		<div class="dqokceoi"> | ||||
| 			<MkA v-for="instance in items" :key="instance.id" v-tooltip.mfm="`Last communicated: ${new Date(instance.lastCommunicatedAt).toLocaleString()}\nStatus: ${getStatus(instance)}`" class="instance" :to="`/instance-info/${instance.host}`"> | ||||
| 				<MkInstanceCardMini :instance="instance"/> | ||||
| 			</MkA> | ||||
| 		</div> | ||||
| 	</MkPagination> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { computed } from 'vue'; | ||||
| import MkButton from '@/components/ui/button.vue'; | ||||
| import MkInput from '@/components/form/input.vue'; | ||||
| import MkSelect from '@/components/form/select.vue'; | ||||
| import MkPagination from '@/components/ui/pagination.vue'; | ||||
| import MkInstanceCardMini from '@/components/instance-card-mini.vue'; | ||||
| import FormSplit from '@/components/form/split.vue'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| 
 | ||||
| let host = $ref(''); | ||||
| let state = $ref('federating'); | ||||
| let sort = $ref('+pubSub'); | ||||
| const pagination = { | ||||
| 	endpoint: 'federation/instances' as const, | ||||
| 	limit: 10, | ||||
| 	offsetMode: true, | ||||
| 	params: computed(() => ({ | ||||
| 		sort: sort, | ||||
| 		host: host !== '' ? host : null, | ||||
| 		...( | ||||
| 			state === 'federating' ? { federating: true } : | ||||
| 			state === 'subscribing' ? { subscribing: true } : | ||||
| 			state === 'publishing' ? { publishing: true } : | ||||
| 			state === 'suspended' ? { suspended: true } : | ||||
| 			state === 'blocked' ? { blocked: true } : | ||||
| 			state === 'notResponding' ? { notResponding: true } : | ||||
| 			{}), | ||||
| 	})), | ||||
| }; | ||||
| 
 | ||||
| function getStatus(instance) { | ||||
| 	if (instance.isSuspended) return 'Suspended'; | ||||
| 	if (instance.isBlocked) return 'Blocked'; | ||||
| 	if (instance.isNotResponding) return 'Error'; | ||||
| 	return 'Alive'; | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
| .taeiyria { | ||||
| 	> .query { | ||||
| 		background: var(--bg); | ||||
| 		margin-bottom: 16px; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .dqokceoi { | ||||
| 	display: grid; | ||||
| 	grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); | ||||
| 	grid-gap: 12px; | ||||
| 
 | ||||
| 	> .instance:hover { | ||||
| 		text-decoration: none; | ||||
| 	} | ||||
| } | ||||
| </style> | ||||
|  | @ -67,6 +67,12 @@ | |||
| 			</FormSection> | ||||
| 		</div> | ||||
| 	</MkSpacer> | ||||
| 	<MkSpacer v-else-if="tab === 'emojis'" :content-max="1000" :margin-min="20"> | ||||
| 		<XEmojis/> | ||||
| 	</MkSpacer> | ||||
| 	<MkSpacer v-else-if="tab === 'federation'" :content-max="1000" :margin-min="20"> | ||||
| 		<XFederation/> | ||||
| 	</MkSpacer> | ||||
| 	<MkSpacer v-else-if="tab === 'charts'" :content-max="1200" :margin-min="20"> | ||||
| 		<MkInstanceStats :chart-limit="500" :detailed="true"/> | ||||
| 	</MkSpacer> | ||||
|  | @ -75,6 +81,8 @@ | |||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { ref, computed } from 'vue'; | ||||
| import XEmojis from './about.emojis.vue'; | ||||
| import XFederation from './about.federation.vue'; | ||||
| import { version, instanceName , host } from '@/config'; | ||||
| import FormLink from '@/components/form/link.vue'; | ||||
| import FormSection from '@/components/form/section.vue'; | ||||
|  | @ -100,10 +108,18 @@ const headerActions = $computed(() => []); | |||
| const headerTabs = $computed(() => [{ | ||||
| 	key: 'overview', | ||||
| 	title: i18n.ts.overview, | ||||
| }, { | ||||
| 	key: 'emojis', | ||||
| 	title: i18n.ts.customEmojis, | ||||
| 	icon: 'fas fa-laugh', | ||||
| }, { | ||||
| 	key: 'federation', | ||||
| 	title: i18n.ts.federation, | ||||
| 	icon: 'fas fa-globe', | ||||
| }, { | ||||
| 	key: 'charts', | ||||
| 	title: i18n.ts.charts, | ||||
| 	icon: 'fas fa-chart-bar', | ||||
| 	icon: 'fas fa-chart-simple', | ||||
| }]); | ||||
| 
 | ||||
| definePageMetadata(computed(() => ({ | ||||
|  |  | |||
|  | @ -201,7 +201,7 @@ const component = $computed(() => { | |||
| 		case 'overview': return defineAsyncComponent(() => import('./overview.vue')); | ||||
| 		case 'users': return defineAsyncComponent(() => import('./users.vue')); | ||||
| 		case 'emojis': return defineAsyncComponent(() => import('./emojis.vue')); | ||||
| 		case 'federation': return defineAsyncComponent(() => import('../federation.vue')); | ||||
| 		//case 'federation': return defineAsyncComponent(() => import('../federation.vue')); | ||||
| 		case 'queue': return defineAsyncComponent(() => import('./queue.vue')); | ||||
| 		case 'files': return defineAsyncComponent(() => import('./files.vue')); | ||||
| 		case 'announcements': return defineAsyncComponent(() => import('./announcements.vue')); | ||||
|  |  | |||
|  | @ -1,60 +0,0 @@ | |||
| <template> | ||||
| <MkStickyContainer> | ||||
| 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> | ||||
| 	<div :class="$style.root"> | ||||
| 		<XCategory v-if="tab === 'category'"/> | ||||
| 	</div> | ||||
| </MkStickyContainer> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { ref, computed } from 'vue'; | ||||
| import XCategory from './emojis.category.vue'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| 
 | ||||
| const tab = ref('category'); | ||||
| 
 | ||||
| function menu(ev) { | ||||
| 	os.popupMenu([{ | ||||
| 		icon: 'fas fa-download', | ||||
| 		text: i18n.ts.export, | ||||
| 		action: async () => { | ||||
| 			os.api('export-custom-emojis', { | ||||
| 			}) | ||||
| 			.then(() => { | ||||
| 				os.alert({ | ||||
| 					type: 'info', | ||||
| 					text: i18n.ts.exportRequested, | ||||
| 				}); | ||||
| 			}).catch((err) => { | ||||
| 				os.alert({ | ||||
| 					type: 'error', | ||||
| 					text: err.message, | ||||
| 				}); | ||||
| 			}); | ||||
| 		}, | ||||
| 	}], ev.currentTarget ?? ev.target); | ||||
| } | ||||
| 
 | ||||
| const headerActions = $computed(() => [{ | ||||
| 	icon: 'fas fa-ellipsis-h', | ||||
| 	handler: menu, | ||||
| }]); | ||||
| 
 | ||||
| const headerTabs = $computed(() => []); | ||||
| 
 | ||||
| definePageMetadata({ | ||||
| 	title: i18n.ts.customEmojis, | ||||
| 	icon: 'fas fa-laugh', | ||||
| 	bg: 'var(--bg)', | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" module> | ||||
| .root { | ||||
| 	max-width: 1000px; | ||||
| 	margin: 0 auto; | ||||
| } | ||||
| </style> | ||||
|  | @ -1,122 +0,0 @@ | |||
| <template> | ||||
| <MkStickyContainer> | ||||
| 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> | ||||
| 	<MkSpacer :content-max="1000"> | ||||
| 		<div class="taeiyria"> | ||||
| 			<div class="query"> | ||||
| 				<MkInput v-model="host" :debounce="true" class=""> | ||||
| 					<template #prefix><i class="fas fa-search"></i></template> | ||||
| 					<template #label>{{ $ts.host }}</template> | ||||
| 				</MkInput> | ||||
| 				<FormSplit style="margin-top: var(--margin);"> | ||||
| 					<MkSelect v-model="state"> | ||||
| 						<template #label>{{ $ts.state }}</template> | ||||
| 						<option value="all">{{ $ts.all }}</option> | ||||
| 						<option value="federating">{{ $ts.federating }}</option> | ||||
| 						<option value="subscribing">{{ $ts.subscribing }}</option> | ||||
| 						<option value="publishing">{{ $ts.publishing }}</option> | ||||
| 						<option value="suspended">{{ $ts.suspended }}</option> | ||||
| 						<option value="blocked">{{ $ts.blocked }}</option> | ||||
| 						<option value="notResponding">{{ $ts.notResponding }}</option> | ||||
| 					</MkSelect> | ||||
| 					<MkSelect v-model="sort"> | ||||
| 						<template #label>{{ $ts.sort }}</template> | ||||
| 						<option value="+pubSub">{{ $ts.pubSub }} ({{ $ts.descendingOrder }})</option> | ||||
| 						<option value="-pubSub">{{ $ts.pubSub }} ({{ $ts.ascendingOrder }})</option> | ||||
| 						<option value="+notes">{{ $ts.notes }} ({{ $ts.descendingOrder }})</option> | ||||
| 						<option value="-notes">{{ $ts.notes }} ({{ $ts.ascendingOrder }})</option> | ||||
| 						<option value="+users">{{ $ts.users }} ({{ $ts.descendingOrder }})</option> | ||||
| 						<option value="-users">{{ $ts.users }} ({{ $ts.ascendingOrder }})</option> | ||||
| 						<option value="+following">{{ $ts.following }} ({{ $ts.descendingOrder }})</option> | ||||
| 						<option value="-following">{{ $ts.following }} ({{ $ts.ascendingOrder }})</option> | ||||
| 						<option value="+followers">{{ $ts.followers }} ({{ $ts.descendingOrder }})</option> | ||||
| 						<option value="-followers">{{ $ts.followers }} ({{ $ts.ascendingOrder }})</option> | ||||
| 						<option value="+caughtAt">{{ $ts.registeredAt }} ({{ $ts.descendingOrder }})</option> | ||||
| 						<option value="-caughtAt">{{ $ts.registeredAt }} ({{ $ts.ascendingOrder }})</option> | ||||
| 						<option value="+lastCommunicatedAt">{{ $ts.lastCommunication }} ({{ $ts.descendingOrder }})</option> | ||||
| 						<option value="-lastCommunicatedAt">{{ $ts.lastCommunication }} ({{ $ts.ascendingOrder }})</option> | ||||
| 					</MkSelect> | ||||
| 				</FormSplit> | ||||
| 			</div> | ||||
| 
 | ||||
| 			<MkPagination v-slot="{items}" ref="instances" :key="host + state" :pagination="pagination"> | ||||
| 				<div class="dqokceoi"> | ||||
| 					<MkA v-for="instance in items" :key="instance.id" v-tooltip.mfm="`Last communicated: ${new Date(instance.lastCommunicatedAt).toLocaleString()}\nStatus: ${getStatus(instance)}`" class="instance" :to="`/instance-info/${instance.host}`"> | ||||
| 						<MkInstanceCardMini :instance="instance"/> | ||||
| 					</MkA> | ||||
| 				</div> | ||||
| 			</MkPagination> | ||||
| 		</div> | ||||
| 	</MkSpacer> | ||||
| </MkStickyContainer> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { computed } from 'vue'; | ||||
| import MkButton from '@/components/ui/button.vue'; | ||||
| import MkInput from '@/components/form/input.vue'; | ||||
| import MkSelect from '@/components/form/select.vue'; | ||||
| import MkPagination from '@/components/ui/pagination.vue'; | ||||
| import MkInstanceCardMini from '@/components/instance-card-mini.vue'; | ||||
| import FormSplit from '@/components/form/split.vue'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| 
 | ||||
| let host = $ref(''); | ||||
| let state = $ref('federating'); | ||||
| let sort = $ref('+pubSub'); | ||||
| const pagination = { | ||||
| 	endpoint: 'federation/instances' as const, | ||||
| 	limit: 10, | ||||
| 	offsetMode: true, | ||||
| 	params: computed(() => ({ | ||||
| 		sort: sort, | ||||
| 		host: host !== '' ? host : null, | ||||
| 		...( | ||||
| 			state === 'federating' ? { federating: true } : | ||||
| 			state === 'subscribing' ? { subscribing: true } : | ||||
| 			state === 'publishing' ? { publishing: true } : | ||||
| 			state === 'suspended' ? { suspended: true } : | ||||
| 			state === 'blocked' ? { blocked: true } : | ||||
| 			state === 'notResponding' ? { notResponding: true } : | ||||
| 			{}), | ||||
| 	})), | ||||
| }; | ||||
| 
 | ||||
| function getStatus(instance) { | ||||
| 	if (instance.isSuspended) return 'Suspended'; | ||||
| 	if (instance.isBlocked) return 'Blocked'; | ||||
| 	if (instance.isNotResponding) return 'Error'; | ||||
| 	return 'Alive'; | ||||
| } | ||||
| 
 | ||||
| const headerActions = $computed(() => []); | ||||
| 
 | ||||
| const headerTabs = $computed(() => []); | ||||
| 
 | ||||
| definePageMetadata({ | ||||
| 	title: i18n.ts.federation, | ||||
| 	icon: 'fas fa-globe', | ||||
| 	bg: 'var(--bg)', | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
| .taeiyria { | ||||
| 	> .query { | ||||
| 		background: var(--bg); | ||||
| 		margin-bottom: 16px; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .dqokceoi { | ||||
| 	display: grid; | ||||
| 	grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); | ||||
| 	grid-gap: 12px; | ||||
| 
 | ||||
| 	> .instance:hover { | ||||
| 		text-decoration: none; | ||||
| 	} | ||||
| } | ||||
| </style> | ||||
|  | @ -1,27 +0,0 @@ | |||
| <template><MkStickyContainer> | ||||
| 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> | ||||
| 		<MkSpacer :content-max="800"> | ||||
| 	<XNotes :pagination="pagination"/> | ||||
| </MkSpacer></MkStickyContainer> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import XNotes from '@/components/notes.vue'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| 
 | ||||
| const pagination = { | ||||
| 	endpoint: 'notes/mentions' as const, | ||||
| 	limit: 10, | ||||
| }; | ||||
| 
 | ||||
| const headerActions = $computed(() => []); | ||||
| 
 | ||||
| const headerTabs = $computed(() => []); | ||||
| 
 | ||||
| definePageMetadata({ | ||||
| 	title: i18n.ts.mentions, | ||||
| 	icon: 'fas fa-at', | ||||
| 	bg: 'var(--bg)', | ||||
| }); | ||||
| </script> | ||||
|  | @ -1,30 +0,0 @@ | |||
| <template><MkStickyContainer> | ||||
| 	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template> | ||||
| 		<MkSpacer :content-max="800"> | ||||
| 	<XNotes :pagination="pagination"/> | ||||
| </MkSpacer></MkStickyContainer> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import XNotes from '@/components/notes.vue'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| 
 | ||||
| const pagination = { | ||||
| 	endpoint: 'notes/mentions' as const, | ||||
| 	limit: 10, | ||||
| 	params: { | ||||
| 		visibility: 'specified', | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| const headerActions = $computed(() => []); | ||||
| 
 | ||||
| const headerTabs = $computed(() => []); | ||||
| 
 | ||||
| definePageMetadata({ | ||||
| 	title: i18n.ts.directNotes, | ||||
| 	icon: 'fas fa-envelope', | ||||
| 	bg: 'var(--bg)', | ||||
| }); | ||||
| </script> | ||||
|  | @ -2,8 +2,14 @@ | |||
| <MkStickyContainer> | ||||
| 	<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template> | ||||
| 	<MkSpacer :content-max="800"> | ||||
| 		<div class="clupoqwt"> | ||||
| 			<XNotifications class="notifications" :include-types="includeTypes" :unread-only="tab === 'unread'"/> | ||||
| 		<div v-if="tab === 'all' || tab === 'unread'"> | ||||
| 			<XNotifications class="notifications" :include-types="includeTypes" :unread-only="unreadOnly"/> | ||||
| 		</div> | ||||
| 		<div v-else-if="tab === 'mentions'"> | ||||
| 			<XNotes :pagination="mentionsPagination"/> | ||||
| 		</div> | ||||
| 		<div v-else-if="tab === 'directNotes'"> | ||||
| 			<XNotes :pagination="directNotesPagination"/> | ||||
| 		</div> | ||||
| 	</MkSpacer> | ||||
| </MkStickyContainer> | ||||
|  | @ -13,12 +19,27 @@ | |||
| import { computed } from 'vue'; | ||||
| import { notificationTypes } from 'misskey-js'; | ||||
| import XNotifications from '@/components/notifications.vue'; | ||||
| import XNotes from '@/components/notes.vue'; | ||||
| import * as os from '@/os'; | ||||
| import { i18n } from '@/i18n'; | ||||
| import { definePageMetadata } from '@/scripts/page-metadata'; | ||||
| 
 | ||||
| let tab = $ref('all'); | ||||
| let includeTypes = $ref<string[] | null>(null); | ||||
| let unreadOnly = $computed(() => tab === 'unread'); | ||||
| 
 | ||||
| const mentionsPagination = { | ||||
| 	endpoint: 'notes/mentions' as const, | ||||
| 	limit: 10, | ||||
| }; | ||||
| 
 | ||||
| const directNotesPagination = { | ||||
| 	endpoint: 'notes/mentions' as const, | ||||
| 	limit: 10, | ||||
| 	params: { | ||||
| 		visibility: 'specified', | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| function setFilter(ev) { | ||||
| 	const typeItems = notificationTypes.map(t => ({ | ||||
|  | @ -38,18 +59,18 @@ function setFilter(ev) { | |||
| 	os.popupMenu(items, ev.currentTarget ?? ev.target); | ||||
| } | ||||
| 
 | ||||
| const headerActions = $computed(() => [{ | ||||
| const headerActions = $computed(() => [tab === 'all' ? { | ||||
| 	text: i18n.ts.filter, | ||||
| 	icon: 'fas fa-filter', | ||||
| 	highlighted: includeTypes != null, | ||||
| 	handler: setFilter, | ||||
| }, { | ||||
| } : undefined, tab === 'all' ? { | ||||
| 	text: i18n.ts.markAllAsRead, | ||||
| 	icon: 'fas fa-check', | ||||
| 	handler: () => { | ||||
| 		os.apiWithDialog('notifications/mark-all-as-read'); | ||||
| 	}, | ||||
| }]); | ||||
| } : undefined].filter(x => x !== undefined)); | ||||
| 
 | ||||
| const headerTabs = $computed(() => [{ | ||||
| 	key: 'all', | ||||
|  | @ -57,6 +78,14 @@ const headerTabs = $computed(() => [{ | |||
| }, { | ||||
| 	key: 'unread', | ||||
| 	title: i18n.ts.unread, | ||||
| }, { | ||||
| 	key: 'mentions', | ||||
| 	title: i18n.ts.mentions, | ||||
| 	icon: 'fas fa-at', | ||||
| }, { | ||||
| 	key: 'directNotes', | ||||
| 	title: i18n.ts.directNotes, | ||||
| 	icon: 'fas fa-envelope', | ||||
| }]); | ||||
| 
 | ||||
| definePageMetadata(computed(() => ({ | ||||
|  | @ -65,8 +94,3 @@ definePageMetadata(computed(() => ({ | |||
| 	bg: 'var(--bg)', | ||||
| }))); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
| .clupoqwt { | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
| <MkContainer> | ||||
| 	<template #header><i class="fas fa-chart-bar" style="margin-right: 0.5em;"></i>{{ $ts.activity }}</template> | ||||
| 	<template #header><i class="fas fa-chart-simple" style="margin-right: 0.5em;"></i>{{ $ts.activity }}</template> | ||||
| 	<template #func> | ||||
| 		<button class="_button" @click="showMenu"> | ||||
| 			<i class="fas fa-ellipsis-h"></i> | ||||
|  | @ -36,8 +36,8 @@ function showMenu(ev: MouseEvent) { | |||
| 		active: true, | ||||
| 		action: () => { | ||||
| 			chartSrc = 'per-user-notes'; | ||||
| 		} | ||||
| 	}/*, { | ||||
| 		}, | ||||
| 	},/*, { | ||||
| 		text: i18n.ts.following, | ||||
| 		action: () => { | ||||
| 			chartSrc = 'per-user-following'; | ||||
|  |  | |||
|  | @ -65,12 +65,6 @@ export const routes = [{ | |||
| }, { | ||||
| 	path: '/explore', | ||||
| 	component: page(() => import('./pages/explore.vue')), | ||||
| }, { | ||||
| 	path: '/federation', | ||||
| 	component: page(() => import('./pages/federation.vue')), | ||||
| }, { | ||||
| 	path: '/emojis', | ||||
| 	component: page(() => import('./pages/emojis.vue')), | ||||
| }, { | ||||
| 	path: '/search', | ||||
| 	component: page(() => import('./pages/search.vue')), | ||||
|  | @ -156,12 +150,6 @@ export const routes = [{ | |||
| }, { | ||||
| 	path: '/my/favorites', | ||||
| 	component: page(() => import('./pages/favorites.vue')), | ||||
| }, { | ||||
| 	path: '/my/messages', | ||||
| 	component: page(() => import('./pages/messages.vue')), | ||||
| }, { | ||||
| 	path: '/my/mentions', | ||||
| 	component: page(() => import('./pages/mentions.vue')), | ||||
| }, { | ||||
| 	name: 'messaging', | ||||
| 	path: '/my/messaging', | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
| <MkContainer :show-header="widgetProps.showHeader" :naked="widgetProps.transparent" class="mkw-activity"> | ||||
| 	<template #header><i class="fas fa-chart-bar"></i>{{ $ts._widgets.activity }}</template> | ||||
| 	<template #header><i class="fas fa-chart-simple"></i>{{ $ts._widgets.activity }}</template> | ||||
| 	<template #func><button class="_button" @click="toggleView()"><i class="fas fa-sort"></i></button></template> | ||||
| 
 | ||||
| 	<div> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue