From 513a8e5de4272da24e70bb57e90ac4f25cab1f55 Mon Sep 17 00:00:00 2001
From: dakkar <dakkar@thenautilus.net>
Date: Sun, 12 May 2024 13:14:44 +0100
Subject: [PATCH 1/3] select note component in <setup>

this makes our templates much more similar to upstream's, making
merges simpler

changing note design is already marked as needing a reload, so having
non-reactive code that selects the note component is not a problem
---
 packages/frontend/src/components/MkNotes.vue  | 21 +++++--------------
 .../src/components/MkNotifications.vue        | 13 ++++++------
 packages/frontend/src/pages/favorites.vue     | 14 ++++++-------
 packages/frontend/src/pages/note.vue          | 13 ++++++------
 packages/frontend/src/pages/user/home.vue     | 12 +++++------
 5 files changed, 29 insertions(+), 44 deletions(-)

diff --git a/packages/frontend/src/components/MkNotes.vue b/packages/frontend/src/components/MkNotes.vue
index 5240d64661..e9043995f5 100644
--- a/packages/frontend/src/components/MkNotes.vue
+++ b/packages/frontend/src/components/MkNotes.vue
@@ -15,7 +15,6 @@ SPDX-License-Identifier: AGPL-3.0-only
 	<template #default="{ items: notes }">
 		<div :class="[$style.root, { [$style.noGap]: noGap }]">
 			<MkDateSeparatedList
-				v-if="defaultStore.state.noteDesign === 'misskey'"
 				ref="notes"
 				v-slot="{ item: note }"
 				:items="notes"
@@ -27,19 +26,6 @@ SPDX-License-Identifier: AGPL-3.0-only
 			>
 				<MkNote :key="note._featuredId_ || note._prId_ || note.id" :class="$style.note" :note="note" :withHardMute="true"/>
 			</MkDateSeparatedList>
-			<MkDateSeparatedList
-				v-else-if="defaultStore.state.noteDesign === 'sharkey'"
-				ref="notes" 
-				v-slot="{ item: note }"
-				:items="notes"
-				:direction="pagination.reversed ? 'up' : 'down'"
-				:reversed="pagination.reversed"
-				:noGap="noGap"
-				:ad="true"
-				:class="$style.notes"
-			>
-				<SkNote :key="note._featuredId_ || note._prId_ || note.id" :class="$style.note" :note="note" :withHardMute="true"/>
-			</MkDateSeparatedList>
 		</div>
 	</template>
 </MkPagination>
@@ -47,14 +33,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <script lang="ts" setup>
 import { shallowRef, ref } from 'vue';
-import MkNote from '@/components/MkNote.vue';
-import SkNote from '@/components/SkNote.vue';
 import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
 import MkPagination, { Paging } from '@/components/MkPagination.vue';
 import { i18n } from '@/i18n.js';
 import { infoImageUrl } from '@/instance.js';
 import { defaultStore } from '@/store.js';
 
+const MkNote = (
+	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNote.vue')).default :
+	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNote.vue')).default :
+	null);
+
 const props = defineProps<{
 	pagination: Paging;
 	noGap?: boolean;
diff --git a/packages/frontend/src/components/MkNotifications.vue b/packages/frontend/src/components/MkNotifications.vue
index 68bf1bf3d8..76dcb5f58d 100644
--- a/packages/frontend/src/components/MkNotifications.vue
+++ b/packages/frontend/src/components/MkNotifications.vue
@@ -14,14 +14,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 		</template>
 
 		<template #default="{ items: notifications }">
-			<MkDateSeparatedList v-if="defaultStore.state.noteDesign === 'misskey'" v-slot="{ item: notification }" :class="$style.list" :items="notifications" :noGap="true">
+			<MkDateSeparatedList v-slot="{ item: notification }" :class="$style.list" :items="notifications" :noGap="true">
 				<MkNote v-if="['reply', 'quote', 'mention'].includes(notification.type)" :key="notification.id + ':note'" :note="notification.note" :withHardMute="true"/>
 				<XNotification v-else :key="notification.id" :notification="notification" :withTime="true" :full="true" class="_panel"/>
 			</MkDateSeparatedList>
-			<MkDateSeparatedList v-else-if="defaultStore.state.noteDesign === 'sharkey'" v-slot="{ item: notification }" :class="$style.list" :items="notifications" :noGap="true">
-				<SkNote v-if="['reply', 'quote', 'mention'].includes(notification.type)" :key="notification.id + ':note'" :note="notification.note" :withHardMute="true"/>
-				<XNotification v-else :key="notification.id" :notification="notification" :withTime="true" :full="true" class="_panel"/>
-			</MkDateSeparatedList>
 		</template>
 	</MkPagination>
 </MkPullToRefresh>
@@ -32,8 +28,6 @@ import { onUnmounted, onDeactivated, onMounted, computed, shallowRef, onActivate
 import MkPagination from '@/components/MkPagination.vue';
 import XNotification from '@/components/MkNotification.vue';
 import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
-import MkNote from '@/components/MkNote.vue';
-import SkNote from '@/components/SkNote.vue';
 import { useStream } from '@/stream.js';
 import { i18n } from '@/i18n.js';
 import { notificationTypes } from '@/const.js';
@@ -42,6 +36,11 @@ import { defaultStore } from '@/store.js';
 import MkPullToRefresh from '@/components/MkPullToRefresh.vue';
 import * as Misskey from 'misskey-js';
 
+const MkNote = (
+	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNote.vue')).default :
+	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNote.vue')).default :
+	null);
+
 const props = defineProps<{
 	excludeTypes?: typeof notificationTypes[number][];
 }>();
diff --git a/packages/frontend/src/pages/favorites.vue b/packages/frontend/src/pages/favorites.vue
index 5835f0c093..a477dc7fcc 100644
--- a/packages/frontend/src/pages/favorites.vue
+++ b/packages/frontend/src/pages/favorites.vue
@@ -16,14 +16,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</template>
 
 			<template #default="{ items }">
-				<MkDateSeparatedList v-if="defaultStore.state.noteDesign === 'misskey'"
-					v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false">
+				<MkDateSeparatedList v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false">
 					<MkNote :key="item.id" :note="item.note" :class="$style.note"/>
 				</MkDateSeparatedList>
-				<MkDateSeparatedList v-if="defaultStore.state.noteDesign === 'sharkey'"
-					v-slot="{ item }" :items="items" :direction="'down'" :noGap="false" :ad="false">
-					<SkNote :key="item.id" :note="item.note" :class="$style.note"/>
-				</MkDateSeparatedList>
 			</template>
 		</MkPagination>
 	</MkSpacer>
@@ -32,14 +27,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <script lang="ts" setup>
 import MkPagination from '@/components/MkPagination.vue';
-import MkNote from '@/components/MkNote.vue';
-import SkNote from '@/components/SkNote.vue';
 import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { infoImageUrl } from '@/instance.js';
 import { defaultStore } from '@/store.js';
 
+const MkNote = (
+	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNote.vue')).default :
+	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNote.vue')).default :
+	null);
+
 const pagination = {
 	endpoint: 'i/favorites' as const,
 	limit: 10,
diff --git a/packages/frontend/src/pages/note.vue b/packages/frontend/src/pages/note.vue
index 418b33754b..e8a7289b0b 100644
--- a/packages/frontend/src/pages/note.vue
+++ b/packages/frontend/src/pages/note.vue
@@ -19,14 +19,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 							<MkButton v-if="note.channelId" rounded :class="$style.loadButton" @click="showNext = 'channel'"><i class="ph-caret-up ph-bold ph-lg"></i> <i class="ph-television-simple ph-bold ph-lg"></i></MkButton>
 							<MkButton rounded :class="$style.loadButton" @click="showNext = 'user'"><i class="ph-caret-up ph-bold ph-lg"></i> <i class="ph-user ph-bold ph-lg"></i></MkButton>
 						</div>
-						<div v-if="defaultStore.state.noteDesign === 'misskey'" class="_margin _gaps_s">
+						<div class="_margin _gaps_s">
 							<MkRemoteCaution v-if="note.user.host != null" :href="note.url ?? note.uri"/>
 							<MkNoteDetailed :key="note.id" v-model:note="note" :initialTab="initialTab" :class="$style.note" :expandAllCws="expandAllCws"/>
 						</div>
-						<div v-else-if="defaultStore.state.noteDesign === 'sharkey'" class="_margin _gaps_s">
-							<MkRemoteCaution v-if="note.user.host != null" :href="note.url ?? note.uri"/>
-							<SkNoteDetailed :key="note.id" v-model:note="note" :initialTab="initialTab" :class="$style.note" :expandAllCws="expandAllCws"/>
-						</div>
 						<div v-if="clips && clips.length > 0" class="_margin">
 							<div style="font-weight: bold; padding: 12px;">{{ i18n.ts.clip }}</div>
 							<div class="_gaps">
@@ -55,9 +51,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 import { computed, watch, ref } from 'vue';
 import * as Misskey from 'misskey-js';
 import type { Paging } from '@/components/MkPagination.vue';
-import MkNoteDetailed from '@/components/MkNoteDetailed.vue';
 import MkNotes from '@/components/MkNotes.vue';
-import SkNoteDetailed from '@/components/SkNoteDetailed.vue';
 import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
 import MkButton from '@/components/MkButton.vue';
 import { misskeyApi } from '@/scripts/misskey-api.js';
@@ -67,6 +61,11 @@ import { dateString } from '@/filters/date.js';
 import MkClipPreview from '@/components/MkClipPreview.vue';
 import { defaultStore } from '@/store.js';
 
+const MkNoteDetailed = (
+	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNoteDetailed.vue')).default :
+	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNoteDetailed.vue')).default :
+	null);
+
 const props = defineProps<{
 	noteId: string;
 	initialTab?: string;
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index 095645636d..b891fc6d2b 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -120,12 +120,9 @@ SPDX-License-Identifier: AGPL-3.0-only
 			</div>
 
 			<div class="contents _gaps">
-				<div v-if="user.pinnedNotes.length > 0 && defaultStore.state.noteDesign === 'misskey'" class="_gaps">
+				<div v-if="user.pinnedNotes.length > 0" class="_gaps">
 					<MkNote v-for="note in user.pinnedNotes" :key="note.id" class="note _panel" :note="note" :pinned="true"/>
 				</div>
-				<div v-else-if="user.pinnedNotes.length > 0 && defaultStore.state.noteDesign === 'sharkey'" class="_gaps">
-					<SkNote v-for="note in user.pinnedNotes" :key="note.id" class="note _panel" :note="note" :pinned="true"/>
-				</div>
 				<MkInfo v-else-if="$i && $i.id === user.id">{{ i18n.ts.userPagePinTip }}</MkInfo>
 				<template v-if="narrow">
 					<MkLazy>
@@ -171,9 +168,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 import { defineAsyncComponent, computed, onMounted, onUnmounted, nextTick, watch, ref } from 'vue';
 import * as Misskey from 'misskey-js';
 import MkTab from '@/components/MkTab.vue';
-import MkNote from '@/components/MkNote.vue';
 import MkNotes from '@/components/MkNotes.vue';
-import SkNote from '@/components/SkNote.vue';
 import MkFollowButton from '@/components/MkFollowButton.vue';
 import MkAccountMoved from '@/components/MkAccountMoved.vue';
 import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
@@ -194,6 +189,11 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
 import { isFollowingVisibleForMe, isFollowersVisibleForMe } from '@/scripts/isFfVisibleForMe.js';
 import { useRouter } from '@/router/supplier.js';
 
+const MkNote = (
+	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNote.vue')).default :
+	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNote.vue')).default :
+	null);
+
 function calcAge(birthdate: string): number {
 	const date = new Date(birthdate);
 	const now = new Date();

From 385ecc30a3a4cda0826d7345b7b9f6c4a5fcb9dc Mon Sep 17 00:00:00 2001
From: dakkar <dakkar@thenautilus.net>
Date: Fri, 21 Jun 2024 11:41:08 +0100
Subject: [PATCH 2/3] don't `await` in `<setup>`
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

`defineAsyncComponent` exists for exactly this purposeā€¦
---
 packages/frontend/src/components/MkNotes.vue         | 11 ++++++-----
 packages/frontend/src/components/MkNotifications.vue | 11 ++++++-----
 packages/frontend/src/pages/favorites.vue            | 10 ++++++----
 packages/frontend/src/pages/note.vue                 | 11 ++++++-----
 packages/frontend/src/pages/user/home.vue            |  9 +++++----
 5 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/packages/frontend/src/components/MkNotes.vue b/packages/frontend/src/components/MkNotes.vue
index e9043995f5..15173fbd99 100644
--- a/packages/frontend/src/components/MkNotes.vue
+++ b/packages/frontend/src/components/MkNotes.vue
@@ -32,17 +32,18 @@ SPDX-License-Identifier: AGPL-3.0-only
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, ref } from 'vue';
+import { defineAsyncComponent, shallowRef, ref } from 'vue';
 import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
 import MkPagination, { Paging } from '@/components/MkPagination.vue';
 import { i18n } from '@/i18n.js';
 import { infoImageUrl } from '@/instance.js';
 import { defaultStore } from '@/store.js';
 
-const MkNote = (
-	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNote.vue')).default :
-	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNote.vue')).default :
-	null);
+const MkNote = defineAsyncComponent(() =>
+	(defaultStore.state.noteDesign === 'misskey') ? import('@/components/MkNote.vue') :
+	(defaultStore.state.noteDesign === 'sharkey') ? import('@/components/SkNote.vue') :
+	null
+);
 
 const props = defineProps<{
 	pagination: Paging;
diff --git a/packages/frontend/src/components/MkNotifications.vue b/packages/frontend/src/components/MkNotifications.vue
index 76dcb5f58d..2dd6c21ef6 100644
--- a/packages/frontend/src/components/MkNotifications.vue
+++ b/packages/frontend/src/components/MkNotifications.vue
@@ -24,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 </template>
 
 <script lang="ts" setup>
-import { onUnmounted, onDeactivated, onMounted, computed, shallowRef, onActivated } from 'vue';
+import { defineAsyncComponent, onUnmounted, onDeactivated, onMounted, computed, shallowRef, onActivated } from 'vue';
 import MkPagination from '@/components/MkPagination.vue';
 import XNotification from '@/components/MkNotification.vue';
 import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
@@ -36,10 +36,11 @@ import { defaultStore } from '@/store.js';
 import MkPullToRefresh from '@/components/MkPullToRefresh.vue';
 import * as Misskey from 'misskey-js';
 
-const MkNote = (
-	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNote.vue')).default :
-	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNote.vue')).default :
-	null);
+const MkNote = defineAsyncComponent(() =>
+	(defaultStore.state.noteDesign === 'misskey') ? import('@/components/MkNote.vue') :
+	(defaultStore.state.noteDesign === 'sharkey') ? import('@/components/SkNote.vue') :
+	null
+);
 
 const props = defineProps<{
 	excludeTypes?: typeof notificationTypes[number][];
diff --git a/packages/frontend/src/pages/favorites.vue b/packages/frontend/src/pages/favorites.vue
index a477dc7fcc..0af84dbed7 100644
--- a/packages/frontend/src/pages/favorites.vue
+++ b/packages/frontend/src/pages/favorites.vue
@@ -28,15 +28,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 <script lang="ts" setup>
 import MkPagination from '@/components/MkPagination.vue';
 import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
+import { defineAsyncComponent } from 'vue';
 import { i18n } from '@/i18n.js';
 import { definePageMetadata } from '@/scripts/page-metadata.js';
 import { infoImageUrl } from '@/instance.js';
 import { defaultStore } from '@/store.js';
 
-const MkNote = (
-	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNote.vue')).default :
-	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNote.vue')).default :
-	null);
+const MkNote = defineAsyncComponent(() =>
+	(defaultStore.state.noteDesign === 'misskey') ? import('@/components/MkNote.vue') :
+	(defaultStore.state.noteDesign === 'sharkey') ? import('@/components/SkNote.vue') :
+	null
+);
 
 const pagination = {
 	endpoint: 'i/favorites' as const,
diff --git a/packages/frontend/src/pages/note.vue b/packages/frontend/src/pages/note.vue
index e8a7289b0b..141bacd526 100644
--- a/packages/frontend/src/pages/note.vue
+++ b/packages/frontend/src/pages/note.vue
@@ -48,7 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 </template>
 
 <script lang="ts" setup>
-import { computed, watch, ref } from 'vue';
+import { defineAsyncComponent, computed, watch, ref } from 'vue';
 import * as Misskey from 'misskey-js';
 import type { Paging } from '@/components/MkPagination.vue';
 import MkNotes from '@/components/MkNotes.vue';
@@ -61,10 +61,11 @@ import { dateString } from '@/filters/date.js';
 import MkClipPreview from '@/components/MkClipPreview.vue';
 import { defaultStore } from '@/store.js';
 
-const MkNoteDetailed = (
-	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNoteDetailed.vue')).default :
-	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNoteDetailed.vue')).default :
-	null);
+const MkNote = defineAsyncComponent(() =>
+	(defaultStore.state.noteDesign === 'misskey') ? import('@/components/MkNote.vue') :
+	(defaultStore.state.noteDesign === 'sharkey') ? import('@/components/SkNote.vue') :
+	null
+);
 
 const props = defineProps<{
 	noteId: string;
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index b891fc6d2b..ccd1a691da 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -189,10 +189,11 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
 import { isFollowingVisibleForMe, isFollowersVisibleForMe } from '@/scripts/isFfVisibleForMe.js';
 import { useRouter } from '@/router/supplier.js';
 
-const MkNote = (
-	(defaultStore.state.noteDesign === 'misskey') ? (await import('@/components/MkNote.vue')).default :
-	(defaultStore.state.noteDesign === 'sharkey') ? (await import('@/components/SkNote.vue')).default :
-	null);
+const MkNote = defineAsyncComponent(() =>
+	(defaultStore.state.noteDesign === 'misskey') ? import('@/components/MkNote.vue') :
+	(defaultStore.state.noteDesign === 'sharkey') ? import('@/components/SkNote.vue') :
+	null
+);
 
 function calcAge(birthdate: string): number {
 	const date = new Date(birthdate);

From 4bcad17013b92522c7967a83417263d39ac573de Mon Sep 17 00:00:00 2001
From: dakkar <dakkar@thenautilus.net>
Date: Sat, 22 Jun 2024 22:17:32 +0100
Subject: [PATCH 3/3] fix "detailed" component load

---
 packages/frontend/src/pages/note.vue | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/packages/frontend/src/pages/note.vue b/packages/frontend/src/pages/note.vue
index 141bacd526..bf6020aaff 100644
--- a/packages/frontend/src/pages/note.vue
+++ b/packages/frontend/src/pages/note.vue
@@ -61,9 +61,9 @@ import { dateString } from '@/filters/date.js';
 import MkClipPreview from '@/components/MkClipPreview.vue';
 import { defaultStore } from '@/store.js';
 
-const MkNote = defineAsyncComponent(() =>
-	(defaultStore.state.noteDesign === 'misskey') ? import('@/components/MkNote.vue') :
-	(defaultStore.state.noteDesign === 'sharkey') ? import('@/components/SkNote.vue') :
+const MkNoteDetailed = defineAsyncComponent(() =>
+	(defaultStore.state.noteDesign === 'misskey') ? import('@/components/MkNoteDetailed.vue') :
+	(defaultStore.state.noteDesign === 'sharkey') ? import('@/components/SkNoteDetailed.vue') :
 	null
 );