diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b4331961..605b8af92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Feat: 絵文字の詳細ダイアログを追加 - Feat: 枠線をつけるMFM`$[border.width=1,style=solid,color=fff,radius=0 ...]`を追加 - デフォルトで枠線からはみ出る部分が隠されるようにしました。初期と同じ挙動にするには`$[border.noclip`が必要です +- Feat: スワイプでタブを切り替えられるように - Enhance: MFM等のコードブロックに全文コピー用のボタンを追加 - Enhance: ハッシュタグ入力時に、本文の末尾の行に何も書かれていない場合は新たにスペースを追加しないように - Enhance: チャンネルノートのピン留めをノートのメニューからできるように diff --git a/locales/index.d.ts b/locales/index.d.ts index 71134544d..a659e790c 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -1204,6 +1204,7 @@ export interface Locale { "ranking": string; "lastNDays": string; "backToTitle": string; + "enableHorizontalSwipe": string; "_bubbleGame": { "howToPlay": string; "_howToPlay": { diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 743a3ca38..8749a5f49 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1201,6 +1201,7 @@ replaying: "リプレイ中" ranking: "ランキング" lastNDays: "直近{n}日" backToTitle: "タイトルへ" +enableHorizontalSwipe: "スワイプしてタブを切り替える" _bubbleGame: howToPlay: "遊び方" diff --git a/packages/frontend/src/components/MkHorizontalSwipe.vue b/packages/frontend/src/components/MkHorizontalSwipe.vue new file mode 100644 index 000000000..2c62aadbf --- /dev/null +++ b/packages/frontend/src/components/MkHorizontalSwipe.vue @@ -0,0 +1,209 @@ + + + + + + diff --git a/packages/frontend/src/pages/about.vue b/packages/frontend/src/pages/about.vue index f402b26ad..4ba1b6da7 100644 --- a/packages/frontend/src/pages/about.vue +++ b/packages/frontend/src/pages/about.vue @@ -6,98 +6,100 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -114,6 +116,7 @@ import FormSplit from '@/components/form/split.vue'; import MkFolder from '@/components/MkFolder.vue'; import MkKeyValue from '@/components/MkKeyValue.vue'; import MkInstanceStats from '@/components/MkInstanceStats.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import { misskeyApi } from '@/scripts/misskey-api.js'; import number from '@/filters/number.js'; import { i18n } from '@/i18n.js'; diff --git a/packages/frontend/src/pages/announcements.vue b/packages/frontend/src/pages/announcements.vue index 5632bf7ca..c31c6d090 100644 --- a/packages/frontend/src/pages/announcements.vue +++ b/packages/frontend/src/pages/announcements.vue @@ -7,34 +7,36 @@ SPDX-License-Identifier: AGPL-3.0-only -
- {{ i18n.ts.youHaveUnreadAnnouncements }} - -
-
{{ i18n.ts.forYou }}
-
- 🆕 - - - - - - - {{ announcement.title }} -
-
- - -
- + +
+ {{ i18n.ts.youHaveUnreadAnnouncements }} + +
+
{{ i18n.ts.forYou }}
+
+ 🆕 + + + + + + + {{ announcement.title }}
-
-
- {{ i18n.ts.gotIt }} -
-
-
-
+
+ + +
+ +
+
+
+ {{ i18n.ts.gotIt }} +
+ + + +
@@ -44,6 +46,7 @@ import { ref, computed } from 'vue'; import MkPagination from '@/components/MkPagination.vue'; import MkButton from '@/components/MkButton.vue'; import MkInfo from '@/components/MkInfo.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import * as os from '@/os.js'; import { misskeyApi } from '@/scripts/misskey-api.js'; import { i18n } from '@/i18n.js'; diff --git a/packages/frontend/src/pages/channel.vue b/packages/frontend/src/pages/channel.vue index 971eca8ca..4cdf2eea7 100644 --- a/packages/frontend/src/pages/channel.vue +++ b/packages/frontend/src/pages/channel.vue @@ -7,53 +7,55 @@ SPDX-License-Identifier: AGPL-3.0-only -
-
- - - -
-
-
-
+ +
+
+ + + +
+
+
+
+
+
{{ i18n.ts.sensitive }}
+
+
+
+
-
{{ i18n.ts.sensitive }}
-
-
- + + + +
+ +
+
+
+
+ {{ i18n.ts.thisChannelArchived }} + + + + + +
+
+ +
+
+
+
+ + + + {{ i18n.ts.search }} +
+
- - - -
- -
-
-
-
- {{ i18n.ts.thisChannelArchived }} - - - - - -
-
- -
-
-
-
- - - - {{ i18n.ts.search }} -
- -
-
+
@@ -58,6 +60,7 @@ import MkInput from '@/components/MkInput.vue'; import MkRadios from '@/components/MkRadios.vue'; import MkButton from '@/components/MkButton.vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { i18n } from '@/i18n.js'; import { useRouter } from '@/global/router/supplier.js'; diff --git a/packages/frontend/src/pages/drive.file.vue b/packages/frontend/src/pages/drive.file.vue index 2c1e5d20a..6a9e90796 100644 --- a/packages/frontend/src/pages/drive.file.vue +++ b/packages/frontend/src/pages/drive.file.vue @@ -9,13 +9,15 @@ SPDX-License-Identifier: AGPL-3.0-only - - - + + + + - - - + + + + @@ -23,6 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { computed, ref, defineAsyncComponent } from 'vue'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; const props = defineProps<{ fileId: string; diff --git a/packages/frontend/src/pages/explore.vue b/packages/frontend/src/pages/explore.vue index f068de888..1b8001436 100644 --- a/packages/frontend/src/pages/explore.vue +++ b/packages/frontend/src/pages/explore.vue @@ -6,17 +6,17 @@ SPDX-License-Identifier: AGPL-3.0-only @@ -26,6 +26,7 @@ import XFeatured from './explore.featured.vue'; import XUsers from './explore.users.vue'; import XRoles from './explore.roles.vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { i18n } from '@/i18n.js'; diff --git a/packages/frontend/src/pages/flash/flash-index.vue b/packages/frontend/src/pages/flash/flash-index.vue index 785201889..53510ea23 100644 --- a/packages/frontend/src/pages/flash/flash-index.vue +++ b/packages/frontend/src/pages/flash/flash-index.vue @@ -7,32 +7,34 @@ SPDX-License-Identifier: AGPL-3.0-only -
- -
- -
-
-
- -
-
- - + +
+
-
-
- -
- +
+
+ + +
+ +
+
- -
+
+ +
+ +
+ +
+
+
+ @@ -42,6 +44,7 @@ import { computed, ref } from 'vue'; import MkFlashPreview from '@/components/MkFlashPreview.vue'; import MkPagination from '@/components/MkPagination.vue'; import MkButton from '@/components/MkButton.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { useRouter } from '@/global/router/supplier.js'; diff --git a/packages/frontend/src/pages/gallery/index.vue b/packages/frontend/src/pages/gallery/index.vue index 0198ab970..9749888fe 100644 --- a/packages/frontend/src/pages/gallery/index.vue +++ b/packages/frontend/src/pages/gallery/index.vue @@ -7,8 +7,8 @@ SPDX-License-Identifier: AGPL-3.0-only -
-
+ +
@@ -26,14 +26,14 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+
-
+
{{ i18n.ts.postToGallery }}
@@ -41,7 +41,7 @@ SPDX-License-Identifier: AGPL-3.0-only
-
+ @@ -51,6 +51,7 @@ import { watch, ref, computed } from 'vue'; import MkFoldableSection from '@/components/MkFoldableSection.vue'; import MkPagination from '@/components/MkPagination.vue'; import MkGalleryPostPreview from '@/components/MkGalleryPostPreview.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { i18n } from '@/i18n.js'; import { useRouter } from '@/global/router/supplier.js'; diff --git a/packages/frontend/src/pages/instance-info.vue b/packages/frontend/src/pages/instance-info.vue index c8a0eeeea..4211dc0d8 100644 --- a/packages/frontend/src/pages/instance-info.vue +++ b/packages/frontend/src/pages/instance-info.vue @@ -7,111 +7,113 @@ SPDX-License-Identifier: AGPL-3.0-only -
-
- - {{ instance.name || `(${i18n.ts.unknown})` }} -
-
- - - - - - - - - - - - -
- - - - - - - -
- {{ i18n.ts.stopActivityDelivery }} - {{ i18n.ts.blockThisInstance }} - {{ i18n.ts.silenceThisInstance }} - Refresh metadata + +
+
+ + {{ instance.name || `(${i18n.ts.unknown})` }}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - host-meta - host-meta.json - nodeinfo - robots.txt - manifest.json - -
-
-
-
- - - - - - - - - - - - - +
+ + + + + + + + + + + +
-
-
{{ i18n.t('recentNHours', { n: 90 }) }}
- -
{{ i18n.t('recentNDays', { n: 90 }) }}
- + + + + + + + +
+ {{ i18n.ts.stopActivityDelivery }} + {{ i18n.ts.blockThisInstance }} + {{ i18n.ts.silenceThisInstance }} + Refresh metadata +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + host-meta + host-meta.json + nodeinfo + robots.txt + manifest.json + +
+
+
+
+ + + + + + + + + + + + + +
+
+
{{ i18n.t('recentNHours', { n: 90 }) }}
+ +
{{ i18n.t('recentNDays', { n: 90 }) }}
+ +
-
-
- - - - - -
-
- - -
+
+ + + + + +
+
+ + +
+ @@ -136,6 +138,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js'; import { i18n } from '@/i18n.js'; import MkUserCardMini from '@/components/MkUserCardMini.vue'; import MkPagination from '@/components/MkPagination.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import { getProxiedImageUrlNullable } from '@/scripts/media-proxy.js'; import { dateString } from '@/filters/date.js'; @@ -144,6 +147,7 @@ const props = defineProps<{ }>(); const tab = ref('overview'); + const chartSrc = ref('instance-requests'); const meta = ref(null); const instance = ref(null); diff --git a/packages/frontend/src/pages/my-clips/index.vue b/packages/frontend/src/pages/my-clips/index.vue index 850222708..468e46838 100644 --- a/packages/frontend/src/pages/my-clips/index.vue +++ b/packages/frontend/src/pages/my-clips/index.vue @@ -7,20 +7,22 @@ SPDX-License-Identifier: AGPL-3.0-only -
- {{ i18n.ts.add }} + +
+ {{ i18n.ts.add }} - - + + + + + +
+
+ - -
-
- - - -
+
+
@@ -36,6 +38,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { clipsCache } from '@/cache.js'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; const pagination = { endpoint: 'clips/list' as const, @@ -44,6 +47,7 @@ const pagination = { }; const tab = ref('my'); + const favorites = ref(null); const pagingComponent = shallowRef>(); diff --git a/packages/frontend/src/pages/notifications.vue b/packages/frontend/src/pages/notifications.vue index d57bda41b..8913a89ad 100644 --- a/packages/frontend/src/pages/notifications.vue +++ b/packages/frontend/src/pages/notifications.vue @@ -7,15 +7,17 @@ SPDX-License-Identifier: AGPL-3.0-only -
- -
-
- -
-
- -
+ +
+ +
+
+ +
+
+ +
+
@@ -24,6 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only import { computed, ref } from 'vue'; import XNotifications from '@/components/MkNotifications.vue'; import MkNotes from '@/components/MkNotes.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import * as os from '@/os.js'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; @@ -96,3 +99,10 @@ definePageMetadata(computed(() => ({ icon: 'ti ti-bell', }))); + + diff --git a/packages/frontend/src/pages/pages.vue b/packages/frontend/src/pages/pages.vue index 22ab9ced0..8b57b1af9 100644 --- a/packages/frontend/src/pages/pages.vue +++ b/packages/frontend/src/pages/pages.vue @@ -7,30 +7,32 @@ SPDX-License-Identifier: AGPL-3.0-only -
- -
- -
-
-
+ +
+ +
+ +
+
+
-
- - -
- -
-
-
+
+ + +
+ +
+
+
-
- -
- -
-
-
+
+ +
+ +
+
+
+
@@ -40,6 +42,7 @@ import { computed, ref } from 'vue'; import MkPagePreview from '@/components/MkPagePreview.vue'; import MkPagination from '@/components/MkPagination.vue'; import MkButton from '@/components/MkButton.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import { i18n } from '@/i18n.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { useRouter } from '@/global/router/supplier.js'; diff --git a/packages/frontend/src/pages/search.vue b/packages/frontend/src/pages/search.vue index 9d5e5697c..b68de805c 100644 --- a/packages/frontend/src/pages/search.vue +++ b/packages/frontend/src/pages/search.vue @@ -7,18 +7,20 @@ SPDX-License-Identifier: AGPL-3.0-only - -
- -
-
- {{ i18n.ts.notesSearchNotAvailable }} -
-
+ + +
+ +
+
+ {{ i18n.ts.notesSearchNotAvailable }} +
+
- - - + + + +
@@ -29,6 +31,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js'; import { $i } from '@/account.js'; import { instance } from '@/instance.js'; import MkInfo from '@/components/MkInfo.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; const XNote = defineAsyncComponent(() => import('./search.note.vue')); const XUser = defineAsyncComponent(() => import('./search.user.vue')); diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 607aaec52..e52a5ee04 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -155,6 +155,7 @@ SPDX-License-Identifier: AGPL-3.0-only {{ i18n.ts.enableInfiniteScroll }} {{ i18n.ts.keepScreenOn }} {{ i18n.ts.disableStreamingTimeline }} + {{ i18n.ts.enableHorizontalSwipe }}
@@ -296,6 +297,7 @@ const keepScreenOn = computed(defaultStore.makeGetterSetter('keepScreenOn')); const disableStreamingTimeline = computed(defaultStore.makeGetterSetter('disableStreamingTimeline')); const useGroupedNotifications = computed(defaultStore.makeGetterSetter('useGroupedNotifications')); const enableSeasonalScreenEffect = computed(defaultStore.makeGetterSetter('enableSeasonalScreenEffect')); +const enableHorizontalSwipe = computed(defaultStore.makeGetterSetter('enableHorizontalSwipe')); watch(lang, () => { miLocalStorage.setItem('lang', lang.value as string); diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue index 6fe8963f5..666a9968b 100644 --- a/packages/frontend/src/pages/timeline.vue +++ b/packages/frontend/src/pages/timeline.vue @@ -7,27 +7,28 @@ SPDX-License-Identifier: AGPL-3.0-only -
- - {{ i18n.ts._timelineDescription[src] }} - - - -
-
- + +
+ + {{ i18n.ts._timelineDescription[src] }} + + +
+
+ +
-
+ @@ -38,6 +39,7 @@ import type { Tab } from '@/components/global/MkPageHeader.tabs.vue'; import MkTimeline from '@/components/MkTimeline.vue'; import MkInfo from '@/components/MkInfo.vue'; import MkPostForm from '@/components/MkPostForm.vue'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; import { scroll } from '@/scripts/scroll.js'; import * as os from '@/os.js'; import { misskeyApi } from '@/scripts/misskey-api.js'; @@ -69,7 +71,9 @@ const withRenotes = ref(true); const withReplies = ref($i ? defaultStore.state.tlWithReplies : false); const onlyFiles = ref(false); -watch(src, () => queue.value = 0); +watch(src, () => { + queue.value = 0; +}); watch(withReplies, (x) => { if ($i) defaultStore.set('tlWithReplies', x); diff --git a/packages/frontend/src/pages/user/index.vue b/packages/frontend/src/pages/user/index.vue index 95869e7b8..603f1bef3 100644 --- a/packages/frontend/src/pages/user/index.vue +++ b/packages/frontend/src/pages/user/index.vue @@ -8,19 +8,21 @@ SPDX-License-Identifier: AGPL-3.0-only
- - - - - - - - - - - - - + + + + + + + + + + + + + + +
@@ -36,6 +38,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js'; import { definePageMetadata } from '@/scripts/page-metadata.js'; import { i18n } from '@/i18n.js'; import { $i } from '@/account.js'; +import MkHorizontalSwipe from '@/components/MkHorizontalSwipe.vue'; const XHome = defineAsyncComponent(() => import('./home.vue')); const XTimeline = defineAsyncComponent(() => import('./index.timeline.vue')); @@ -57,6 +60,7 @@ const props = withDefaults(defineProps<{ }); const tab = ref(props.page); + const user = ref(null); const error = ref(null); diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index e3a85377d..21b796caa 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -427,6 +427,10 @@ export const defaultStore = markRaw(new Storage('base', { sfxVolume: 1, }, }, + enableHorizontalSwipe: { + where: 'device', + default: true, + }, sound_masterVolume: { where: 'device',