From 3604c470aa0fa37e74e4c2a8ac20d5bca3ad5271 Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Mon, 26 Feb 2024 16:56:57 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=81=E3=83=A5=E3=83=BC=E3=83=88?= =?UTF-8?q?=E3=83=AA=E3=82=A2=E3=83=AB=E3=82=92=E7=8B=AC=E7=AB=8B=E3=83=9A?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E3=81=AB=E3=81=97=E3=81=A6=E5=88=9D=E6=9C=9F?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=82=A6=E3=82=A3=E3=82=B6=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=A8=E7=B5=B1=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/index.d.ts | 165 +++++---- locales/ja-JP.yml | 45 ++- packages/frontend/.storybook/generate.tsx | 2 - packages/frontend/package.json | 1 + packages/frontend/src/_boot_.ts | 2 +- packages/frontend/src/boot/common.ts | 9 + packages/frontend/src/boot/main-boot.ts | 6 - ...ue => MkTutorial.FollowUsers.UserCard.vue} | 0 ....Follow.vue => MkTutorial.FollowUsers.vue} | 5 +- ...ialDialog.Note.vue => MkTutorial.Note.vue} | 6 +- ...g.PostNote.vue => MkTutorial.PostNote.vue} | 2 +- .../components/MkTutorial.PrivacySettings.vue | 48 +++ ...Sensitive.vue => MkTutorial.Sensitive.vue} | 2 +- ...g.Timeline.vue => MkTutorial.Timeline.vue} | 3 +- .../frontend/src/components/MkTutorial.vue | 326 ++++++++++++++++++ .../src/components/MkTutorialDialog.vue | 162 +-------- .../MkUserSetupDialog.Follow.stories.impl.ts | 56 --- .../MkUserSetupDialog.Privacy.stories.impl.ts | 36 -- .../components/MkUserSetupDialog.Privacy.vue | 71 ---- .../MkUserSetupDialog.Profile.stories.impl.ts | 36 -- .../components/MkUserSetupDialog.Profile.vue | 103 ------ .../MkUserSetupDialog.User.stories.impl.ts | 37 -- .../MkUserSetupDialog.stories.impl.ts | 56 --- .../src/components/MkUserSetupDialog.vue | 257 -------------- .../frontend/src/components/form/link.vue | 41 ++- packages/frontend/src/pages/onboarding.vue | 312 +++++++++++++++++ .../frontend/src/pages/signup-complete.vue | 2 +- packages/frontend/src/router/definition.ts | 4 + .../frontend/src/scripts/reaction-picker.ts | 4 + pnpm-lock.yaml | 79 +++-- 30 files changed, 935 insertions(+), 943 deletions(-) rename packages/frontend/src/components/{MkUserSetupDialog.User.vue => MkTutorial.FollowUsers.UserCard.vue} (100%) rename packages/frontend/src/components/{MkUserSetupDialog.Follow.vue => MkTutorial.FollowUsers.vue} (82%) rename packages/frontend/src/components/{MkTutorialDialog.Note.vue => MkTutorial.Note.vue} (89%) rename packages/frontend/src/components/{MkTutorialDialog.PostNote.vue => MkTutorial.PostNote.vue} (96%) create mode 100644 packages/frontend/src/components/MkTutorial.PrivacySettings.vue rename packages/frontend/src/components/{MkTutorialDialog.Sensitive.vue => MkTutorial.Sensitive.vue} (95%) rename packages/frontend/src/components/{MkTutorialDialog.Timeline.vue => MkTutorial.Timeline.vue} (93%) create mode 100644 packages/frontend/src/components/MkTutorial.vue delete mode 100644 packages/frontend/src/components/MkUserSetupDialog.Follow.stories.impl.ts delete mode 100644 packages/frontend/src/components/MkUserSetupDialog.Privacy.stories.impl.ts delete mode 100644 packages/frontend/src/components/MkUserSetupDialog.Privacy.vue delete mode 100644 packages/frontend/src/components/MkUserSetupDialog.Profile.stories.impl.ts delete mode 100644 packages/frontend/src/components/MkUserSetupDialog.Profile.vue delete mode 100644 packages/frontend/src/components/MkUserSetupDialog.User.stories.impl.ts delete mode 100644 packages/frontend/src/components/MkUserSetupDialog.stories.impl.ts delete mode 100644 packages/frontend/src/components/MkUserSetupDialog.vue create mode 100644 packages/frontend/src/pages/onboarding.vue diff --git a/locales/index.d.ts b/locales/index.d.ts index d483fea837..44dcfc63fc 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4884,6 +4884,14 @@ export interface Locale extends ILocale { * スワイプしてタブを切り替える */ "enableHorizontalSwipe": string; + /** + * チュートリアルをスキップできないようにする + */ + "prohibitSkippingTutorial": string; + /** + * 新規登録したユーザーに表示されるチュートリアルをスキップできないようにします。チュートリアルを完了せずチュートリアルページを回避した場合でも、強制的にリダイレクトされます。 + */ + "prohibitSkippingTutorialDescription": string; "_bubbleGame": { /** * 遊び方 @@ -4954,68 +4962,6 @@ export interface Locale extends ILocale { */ "silenceDescription": string; }; - "_initialAccountSetting": { - /** - * アカウントの作成が完了しました! - */ - "accountCreated": string; - /** - * さっそくアカウントの初期設定を行いましょう。 - */ - "letsStartAccountSetup": string; - /** - * まずはあなたのプロフィールを設定しましょう。 - */ - "letsFillYourProfile": string; - /** - * プロフィール設定 - */ - "profileSetting": string; - /** - * プライバシー設定 - */ - "privacySetting": string; - /** - * これらの設定は後から変更できます。 - */ - "theseSettingsCanEditLater": string; - /** - * この他にも様々な設定を「設定」ページから行えます。ぜひ後で確認してみてください。 - */ - "youCanEditMoreSettingsInSettingsPageLater": string; - /** - * タイムラインを構築するため、気になるユーザーをフォローしてみましょう。 - */ - "followUsers": string; - /** - * プッシュ通知を有効にすると{name}の通知をお使いのデバイスで受け取ることができます。 - */ - "pushNotificationDescription": ParameterizedString<"name">; - /** - * 初期設定が完了しました! - */ - "initialAccountSettingCompleted": string; - /** - * {name}をお楽しみください! - */ - "haveFun": ParameterizedString<"name">; - /** - * このまま{name}(Misskey)の使い方についてのチュートリアルに進むこともできますが、ここで中断してすぐに使い始めることもできます。 - */ - "youCanContinueTutorial": ParameterizedString<"name">; - /** - * チュートリアルを開始 - */ - "startTutorial": string; - /** - * 初期設定をスキップしますか? - */ - "skipAreYouSure": string; - /** - * 初期設定をあとでやり直しますか? - */ - "laterAreYouSure": string; - }; "_initialTutorial": { /** * チュートリアルを見る @@ -5129,6 +5075,16 @@ export interface Locale extends ILocale { */ "description3": ParameterizedString<"link">; }; + "_followUsers": { + /** + * 誰もフォローしていない状態だと、ホームタイムラインには何も表示されません。 + */ + "description1": string; + /** + * タイムラインを構築するため、気になるユーザーをフォローしてみましょう。 + */ + "description2": string; + }; "_postNote": { /** * ノートの投稿設定 @@ -5229,6 +5185,30 @@ export interface Locale extends ILocale { */ "doItToContinue": string; }; + "_pushNotification": { + /** + * プッシュ通知を有効にすると{name}の通知をお使いのデバイスで受け取ることができます。 + */ + "description": ParameterizedString<"name">; + }; + "_privacySettings": { + /** + * プライバシー設定 + */ + "title": string; + /** + * 多くのユーザーが利用しているプライバシー関連の設定項目をリストアップしました。必要に応じて変更してください。 + */ + "description1": string; + /** + * これらの設定は後から変更できます。 + */ + "theseSettingsCanEditLater": string; + /** + * この他にも様々な設定を「設定」ページから行えます。ぜひ後で確認してみてください。 + */ + "youCanEditMoreSettingsInSettingsPageLater": string; + }; "_done": { /** * チュートリアルは終了です🎉 @@ -5238,6 +5218,67 @@ export interface Locale extends ILocale { * ここで紹介した機能はほんの一部にすぎません。Misskeyの使い方をより詳しく知るには、{link}をご覧ください。 */ "description": ParameterizedString<"link">; + /** + * {name}をお楽しみください! + */ + "haveFun": ParameterizedString<"name">; + /** + * このチュートリアルは、「もっと!」→「情報」→「チュートリアルを見る」からいつでも見返すことができます。 + */ + "youCanReferTutorialBy": string; + }; + "_onboardingLanding": { + /** + * アカウントの作成が完了しました! + */ + "accountCreated": string; + /** + * ようこそ、{name}へ! + */ + "welcomeToX": ParameterizedString<"name">; + /** + * 「{name}に登録したは良いものの、どう使えばいいか分からない…💦」といったことを防ぐために、まずはMisskeyの基本的な使い方を学びましょう。 + */ + "description": ParameterizedString<"name">; + /** + * このチュートリアルの所要時間は{min}分程度です。 + * チュートリアルを完了すると実績が解除されます。 + */ + "takesAbout": ParameterizedString<"min">; + }; + "_onboardingDone": { + /** + * お疲れ様でした!次のステップに進んで、{name}をもっと楽しめるようにしましょう。 + */ + "description": ParameterizedString<"name">; + /** + * 元のページに戻る + */ + "backToOriginalPath": string; + /** + * あなたがアクセスしようとしていたページに戻ります。 + */ + "backToOriginalPathDescription": string; + /** + * プロフィール設定 + */ + "profile": string; + /** + * 他のユーザーが親しみやすいように、プロフィールをつくりましょう。 + */ + "profileDescription": string; + /** + * 人気のノートやユーザーを見つけて交流をはじめましょう。 + */ + "exploreDescription": string; + /** + * ホーム画面に進む + */ + "goToTimeline": string; + /** + * 設定等を行わず、通常のホーム画面(タイムライン)に進みます。 + */ + "goToTimelineDescription": string; }; }; "_timelineDescription": { diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 7e16619fc7..401285ca3c 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1217,6 +1217,8 @@ hemisphere: "お住まいの地域" withSensitive: "センシティブなファイルを含むノートを表示" userSaysSomethingSensitive: "{name}のセンシティブなファイルを含む投稿" enableHorizontalSwipe: "スワイプしてタブを切り替える" +prohibitSkippingTutorial: "チュートリアルをスキップできないようにする" +prohibitSkippingTutorialDescription: "新規登録したユーザーに表示されるチュートリアルをスキップできないようにします。チュートリアルを完了せずチュートリアルページを回避した場合でも、強制的にリダイレクトされます。" _bubbleGame: howToPlay: "遊び方" @@ -1239,23 +1241,6 @@ _announcement: silence: "非通知" silenceDescription: "オンにすると、このお知らせは通知されず、既読にする必要もなくなります。" -_initialAccountSetting: - accountCreated: "アカウントの作成が完了しました!" - letsStartAccountSetup: "さっそくアカウントの初期設定を行いましょう。" - letsFillYourProfile: "まずはあなたのプロフィールを設定しましょう。" - profileSetting: "プロフィール設定" - privacySetting: "プライバシー設定" - theseSettingsCanEditLater: "これらの設定は後から変更できます。" - youCanEditMoreSettingsInSettingsPageLater: "この他にも様々な設定を「設定」ページから行えます。ぜひ後で確認してみてください。" - followUsers: "タイムラインを構築するため、気になるユーザーをフォローしてみましょう。" - pushNotificationDescription: "プッシュ通知を有効にすると{name}の通知をお使いのデバイスで受け取ることができます。" - initialAccountSettingCompleted: "初期設定が完了しました!" - haveFun: "{name}をお楽しみください!" - youCanContinueTutorial: "このまま{name}(Misskey)の使い方についてのチュートリアルに進むこともできますが、ここで中断してすぐに使い始めることもできます。" - startTutorial: "チュートリアルを開始" - skipAreYouSure: "初期設定をスキップしますか?" - laterAreYouSure: "初期設定をあとでやり直しますか?" - _initialTutorial: launchTutorial: "チュートリアルを見る" title: "チュートリアル" @@ -1287,6 +1272,9 @@ _initialTutorial: global: "接続している他のすべてのサーバーからの投稿を見られます。" description2: "それぞれのタイムラインは、画面上部でいつでも切り替えられます。" description3: "その他にも、リストタイムラインやチャンネルタイムラインなどがあります。詳しくは{link}をご覧ください。" + _followUsers: + description1: "誰もフォローしていない状態だと、ホームタイムラインには何も表示されません。" + description2: "タイムラインを構築するため、気になるユーザーをフォローしてみましょう。" _postNote: title: "ノートの投稿設定" description1: "Misskeyにノートを投稿する際には、様々なオプションの設定が可能です。投稿フォームはこのようになっています。" @@ -1315,9 +1303,32 @@ _initialTutorial: method: "添付ファイルをセンシティブにする際は、そのファイルをクリックしてメニューを開き、「センシティブとして設定」をクリックします。" sensitiveSucceeded: "ファイルを添付する際は、サーバーのガイドラインに従ってセンシティブを適切に設定してください。" doItToContinue: "画像をセンシティブに設定すると先に進めるようになります。" + _pushNotification: + description: "プッシュ通知を有効にすると{name}の通知をお使いのデバイスで受け取ることができます。" + _privacySettings: + title: "プライバシー設定" + description1: "多くのユーザーが利用しているプライバシー関連の設定項目をリストアップしました。必要に応じて変更してください。" + theseSettingsCanEditLater: "これらの設定は後から変更できます。" + youCanEditMoreSettingsInSettingsPageLater: "この他にも様々な設定を「設定」ページから行えます。ぜひ後で確認してみてください。" _done: title: "チュートリアルは終了です🎉" description: "ここで紹介した機能はほんの一部にすぎません。Misskeyの使い方をより詳しく知るには、{link}をご覧ください。" + haveFun: "{name}をお楽しみください!" + youCanReferTutorialBy: "このチュートリアルは、「もっと!」→「情報」→「チュートリアルを見る」からいつでも見返すことができます。" + _onboardingLanding: + accountCreated: "アカウントの作成が完了しました!" + welcomeToX: "ようこそ、{name}へ!" + description: "「{name}に登録したは良いものの、どう使えばいいか分からない…💦」といったことを防ぐために、まずはMisskeyの基本的な使い方を学びましょう。" + takesAbout: "このチュートリアルの所要時間は{min}分程度です。\nチュートリアルを完了すると実績が解除されます。" + _onboardingDone: + description: "お疲れ様でした!次のステップに進んで、{name}をもっと楽しめるようにしましょう。" + backToOriginalPath: "元のページに戻る" + backToOriginalPathDescription: "あなたがアクセスしようとしていたページに戻ります。" + profile: "プロフィール設定" + profileDescription: "他のユーザーが親しみやすいように、プロフィールをつくりましょう。" + exploreDescription: "人気のノートやユーザーを見つけて交流をはじめましょう。" + goToTimeline: "ホーム画面に進む" + goToTimelineDescription: "設定等を行わず、通常のホーム画面(タイムライン)に進みます。" _timelineDescription: home: "ホームタイムラインでは、あなたがフォローしているアカウントの投稿を見られます。" diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx index 76c5b6be4b..0f9c8da623 100644 --- a/packages/frontend/.storybook/generate.tsx +++ b/packages/frontend/.storybook/generate.tsx @@ -406,8 +406,6 @@ function toStories(component: string): Promise { glob('src/components/MkDigitalClock.vue'), glob('src/components/MkGalleryPostPreview.vue'), glob('src/components/MkSignupServerRules.vue'), - glob('src/components/MkUserSetupDialog.vue'), - glob('src/components/MkUserSetupDialog.*.vue'), glob('src/components/MkInviteCode.vue'), glob('src/pages/user/home.vue'), ]); diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 91a391ac08..04d4c6e809 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -97,6 +97,7 @@ "@storybook/vue3": "8.0.0-beta.2", "@storybook/vue3-vite": "8.0.0-beta.2", "@testing-library/vue": "8.0.2", + "@types/canvas-confetti": "^1.6.4", "@types/escape-regexp": "0.0.3", "@types/estree": "1.0.5", "@types/matter-js": "0.19.6", diff --git a/packages/frontend/src/_boot_.ts b/packages/frontend/src/_boot_.ts index 875353f8a4..a532c9b8ad 100644 --- a/packages/frontend/src/_boot_.ts +++ b/packages/frontend/src/_boot_.ts @@ -10,7 +10,7 @@ import '@/style.scss'; import { mainBoot } from '@/boot/main-boot.js'; import { subBoot } from '@/boot/sub-boot.js'; -const subBootPaths = ['/share', '/auth', '/miauth', '/signup-complete']; +const subBootPaths = ['/share', '/auth', '/miauth', '/signup-complete', '/onboarding']; if (subBootPaths.some(i => location.pathname === i || location.pathname.startsWith(i + '/'))) { subBoot(); diff --git a/packages/frontend/src/boot/common.ts b/packages/frontend/src/boot/common.ts index 681beaf00f..ae4278ea28 100644 --- a/packages/frontend/src/boot/common.ts +++ b/packages/frontend/src/boot/common.ts @@ -21,6 +21,7 @@ import { getUrlWithoutLoginId } from '@/scripts/login-id.js'; import { getAccountFromId } from '@/scripts/get-account-from-id.js'; import { deckStore } from '@/ui/deck/deck-store.js'; import { miLocalStorage } from '@/local-storage.js'; +import { claimedAchievements } from '@/scripts/achievements.js'; import { fetchCustomEmojis } from '@/custom-emojis.js'; import { setupRouter } from '@/router/definition.js'; @@ -118,6 +119,14 @@ export async function common(createVue: () => App) { await defaultStore.ready; await deckStore.ready; + // 2024年3月1日JST以降に作成されたアカウントで、チュートリアル完了していない場合、チュートリアルにリダイレクト + if ($i && new Date($i.createdAt).getTime() >= 1709218800000 && !claimedAchievements.includes('tutorialCompleted') && !location.pathname.startsWith('/onboarding') && !location.pathname.startsWith('/signup-complete')) { + const param = new URLSearchParams(); + param.set('redirected_from', location.pathname + location.search + location.hash); + location.replace('/onboarding?' + param.toString()); + return; + } + const fetchInstanceMetaPromise = fetchInstance(); fetchInstanceMetaPromise.then(() => { diff --git a/packages/frontend/src/boot/main-boot.ts b/packages/frontend/src/boot/main-boot.ts index 61f04678bf..d2d415b3a7 100644 --- a/packages/frontend/src/boot/main-boot.ts +++ b/packages/frontend/src/boot/main-boot.ts @@ -102,12 +102,6 @@ export async function mainBoot() { // only add post shortcuts if logged in hotkeys['p|n'] = post; - defaultStore.loaded.then(() => { - if (defaultStore.state.accountSetupWizard !== -1) { - popup(defineAsyncComponent(() => import('@/components/MkUserSetupDialog.vue')), {}, {}, 'closed'); - } - }); - for (const announcement of ($i.unreadAnnouncements ?? []).filter(x => x.display === 'dialog')) { popup(defineAsyncComponent(() => import('@/components/MkAnnouncementDialog.vue')), { announcement, diff --git a/packages/frontend/src/components/MkUserSetupDialog.User.vue b/packages/frontend/src/components/MkTutorial.FollowUsers.UserCard.vue similarity index 100% rename from packages/frontend/src/components/MkUserSetupDialog.User.vue rename to packages/frontend/src/components/MkTutorial.FollowUsers.UserCard.vue diff --git a/packages/frontend/src/components/MkUserSetupDialog.Follow.vue b/packages/frontend/src/components/MkTutorial.FollowUsers.vue similarity index 82% rename from packages/frontend/src/components/MkUserSetupDialog.Follow.vue rename to packages/frontend/src/components/MkTutorial.FollowUsers.vue index 1524ea0ec9..df2a8150e1 100644 --- a/packages/frontend/src/components/MkUserSetupDialog.Follow.vue +++ b/packages/frontend/src/components/MkTutorial.FollowUsers.vue @@ -5,7 +5,8 @@ SPDX-License-Identifier: AGPL-3.0-only