This commit is contained in:
kakkokari-gtyih 2024-03-22 23:00:59 +09:00
parent 97a904c90f
commit 0dd0b08d60
10 changed files with 49 additions and 24 deletions

5
locales/index.d.ts vendored
View File

@ -5323,6 +5323,11 @@ export interface Locale extends ILocale {
*
*/
"takesAbout": ParameterizedString<"min">;
/**
*
* Misskeyを使い始めることはできません
*/
"adminForcesToTakeTutorial": string;
};
"_onboardingDone": {
/**

View File

@ -1340,6 +1340,7 @@ _initialTutorial:
welcomeToX: "ようこそ、{name}へ!"
description: "「{name}に登録したは良いものの、どう使えばいいか分からない…💦」といったことを防ぐために、まずはMisskeyの基本的な使い方を学びましょう。"
takesAbout: "このチュートリアルの所要時間は{min}分程度です。\nチュートリアルを完了すると実績が解除されます。"
adminForcesToTakeTutorial: "このサーバーの管理者は新規ユーザーにチュートリアルを完了することを義務付けています。\nチュートリアルを完了するまでMisskeyを使い始めることはできません。"
_onboardingDone:
description: "お疲れ様でした!次のステップに進んで、{name}をもっと楽しめるようにしましょう。"
backToOriginalPath: "元のページに戻る"

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@ -119,8 +119,8 @@ export async function common(createVue: () => App<Element>) {
await defaultStore.ready;
await deckStore.ready;
// 2024年3月1日JST以降に作成されたアカウントで、チュートリアルを完了していない通常ユーザーの場合、チュートリアルにリダイレクト
if (!instance.canSkipInitialTutorial && $i && !iAmModerator && new Date($i.createdAt).getTime() >= 1709218800000 && !claimedAchievements.includes('tutorialCompleted') && !location.pathname.startsWith('/onboarding') && !location.pathname.startsWith('/signup-complete')) {
// 2024年4月1日JST以降に作成されたアカウントで、チュートリアルを完了していない通常ユーザーの場合、チュートリアルにリダイレクト
if (!instance.canSkipInitialTutorial && $i && !iAmModerator && new Date($i.createdAt).getTime() >= 1711897200000 && !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());

View File

@ -537,6 +537,8 @@ function pushVisibleUser(user: Misskey.entities.UserDetailed) {
}
function addVisibleUser() {
if (props.mock) return;
os.selectUser().then(user => {
pushVisibleUser(user);
@ -861,6 +863,8 @@ function cancel() {
}
function insertMention() {
if (props.mock) return;
os.selectUser({ localOnly: localOnly.value, includeSelf: true }).then(user => {
insertTextAtCursor(textareaEl.value, '@' + Misskey.acct.toString(user) + ' ');
});

View File

@ -5,15 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div class="_gaps">
<div style="word-break: auto-phrase; text-align: center;">{{ i18n.ts._initialTutorial._followUsers.description1 }}</div>
<div style="word-break: auto-phrase; text-align: center;">{{ i18n.ts._initialTutorial._followUsers.description2 }}</div>
<div style="word-break: auto-phrase; text-align: center;">{{ i18n.ts._initialTutorial._followUsers.description1 }}<br>{{ i18n.ts._initialTutorial._followUsers.description2 }}</div>
<MkFolder :defaultOpen="true">
<template #label>{{ i18n.ts.recommended }}</template>
<MkPagination :pagination="pinnedUsers">
<template #default="{ items }">
<div :class="$style.users">
<div class="_gaps_s">
<XUser v-for="item in (items as Misskey.entities.UserDetailed[])" :key="item.id" :user="item"/>
</div>
</template>
@ -25,7 +24,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkPagination :pagination="popularUsers">
<template #default="{ items }">
<div :class="$style.users">
<div class="_gaps_s">
<XUser v-for="item in (items as Misskey.entities.UserDetailed[])" :key="item.id" :user="item"/>
</div>
</template>
@ -58,12 +57,3 @@ const popularUsers: Paging = {
},
};
</script>
<style lang="scss" module>
.users {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
grid-gap: var(--margin);
justify-content: center;
}
</style>

View File

@ -15,7 +15,10 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
<div v-else-if="phase === 'howToReact'" class="_gaps">
<div style="word-break: auto-phrase; text-align: center; padding: 0 16px;">{{ i18n.ts._initialTutorial._reaction.description }}</div>
<div class="_gaps_s">
<div style="word-break: auto-phrase; text-align: center; padding: 0 16px;">{{ i18n.ts._initialTutorial._reaction.description }}</div>
<img :class="$style.image" src="/client-assets/tutorial/reaction.png"/>
</div>
<div>{{ i18n.ts._initialTutorial._reaction.letsTryReacting }}</div>
<MkNote :class="$style.exampleNoteRoot" :note="exampleNote" :mock="true" @reaction="addReaction" @removeReaction="removeReaction"/>
<div v-if="onceReacted"><b style="color: var(--accent);"><i class="ti ti-check"></i> {{ i18n.ts._initialTutorial.wellDone }}</b> {{ i18n.ts._initialTutorial._reaction.reactNotification }}<br>{{ i18n.ts._initialTutorial._reaction.reactDone }}</div>
@ -78,7 +81,11 @@ function addReaction(emoji) {
emit('reacted');
exampleNote.reactions[emoji] = 1;
exampleNote.myReaction = emoji;
doNotification(emoji);
//
setTimeout(() => {
doNotification(emoji);
}, 200);
}
function doNotification(emoji: string): void {
@ -114,4 +121,10 @@ function removeReaction(emoji) {
height: 1px;
background: var(--divider);
}
.image {
max-width: 300px;
margin: 0 auto;
border-radius: var(--radius);
}
</style>

View File

@ -11,6 +11,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="isLocked">{{ i18n.ts.makeFollowManuallyApprove }}<template #caption>{{ i18n.ts.lockedAccountInfo }}</template></MkSwitch>
<MkSwitch v-model="publicReactions">{{ i18n.ts.makeReactionsPublic }}<template #caption>{{ i18n.ts.makeReactionsPublicDescription }}</template></MkSwitch>
<MkSwitch v-model="hideOnlineStatus">{{ i18n.ts.hideOnlineStatus }}<template #caption>{{ i18n.ts.hideOnlineStatusDescription }}</template></MkSwitch>
<MkSwitch v-model="noCrawle">{{ i18n.ts.noCrawle }}<template #caption>{{ i18n.ts.noCrawleDescription }}</template></MkSwitch>
@ -27,15 +29,20 @@ import { i18n } from '@/i18n.js';
import MkSwitch from '@/components/MkSwitch.vue';
import MkInfo from '@/components/MkInfo.vue';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { signinRequired } from '@/account.js';
const isLocked = ref(false);
const hideOnlineStatus = ref(false);
const noCrawle = ref(false);
const preventAiLearning = ref(true);
const $i = signinRequired();
watch([isLocked, hideOnlineStatus, noCrawle, preventAiLearning], () => {
const isLocked = ref($i.isLocked);
const publicReactions = ref($i.publicReactions);
const hideOnlineStatus = ref($i.hideOnlineStatus);
const noCrawle = ref($i.noCrawle);
const preventAiLearning = ref($i.preventAiLearning);
watch([isLocked, publicReactions, hideOnlineStatus, noCrawle, preventAiLearning], () => {
misskeyApi('i/update', {
isLocked: !!isLocked.value,
publicReactions: !!publicReactions.value,
hideOnlineStatus: !!hideOnlineStatus.value,
noCrawle: !!noCrawle.value,
preventAiLearning: !!preventAiLearning.value,

View File

@ -43,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer :marginMin="20" :marginMax="28" :class="$style.pageMain">
<div class="_gaps">
<XNote phase="howToReact" @reacted="isReactionTutorialPushed = true"/>
<b v-if="!isReactionTutorialPushed">{{ i18n.ts._initialTutorial._reaction.reactToContinue }}</b>
<b v-if="!isReactionTutorialPushed" :class="$style.actionWaitText">{{ i18n.ts._initialTutorial._reaction.reactToContinue }}</b>
</div>
</MkSpacer>
</div>
@ -74,7 +74,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer :marginMin="20" :marginMax="28" :class="$style.pageMain">
<div class="_gaps">
<XSensitive @succeeded="isSensitiveTutorialSucceeded = true"/>
<b v-if="!isSensitiveTutorialSucceeded">{{ i18n.ts._initialTutorial._howToMakeAttachmentsSensitive.doItToContinue }}</b>
<b v-if="!isSensitiveTutorialSucceeded" :class="$style.actionWaitText">{{ i18n.ts._initialTutorial._howToMakeAttachmentsSensitive.doItToContinue }}</b>
</div>
</MkSpacer>
</div>
@ -299,6 +299,10 @@ function prev() {
margin-bottom: 56px;
}
.actionWaitText {
color: var(--error);
}
.pageFooter {
position: sticky;
bottom: 0;

View File

@ -55,6 +55,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div>{{ i18n.tsx._initialTutorial._onboardingLanding.description({ name: instance.name ?? host }) }}</div>
<MkButton large primary rounded gradate style="margin: 16px auto 0;" data-cy-user-setup-continue @click="next">{{ i18n.ts.start }} <i class="ti ti-arrow-right"></i></MkButton>
<MkButton v-if="instance.canSkipInitialTutorial" transparent rounded style="margin: 0 auto;" data-cy-user-setup-close @click="cancel">{{ i18n.ts.later }}</MkButton>
<MkInfo v-else warn style="width: fit-content; margin: 0 auto; text-align: start; white-space: pre-wrap;">{{ i18n.ts._initialTutorial._onboardingLanding.adminForcesToTakeTutorial }}</MkInfo>
<MkInfo style="width: fit-content; margin: 0 auto; text-align: start; white-space: pre-wrap;">{{ i18n.tsx._initialTutorial._onboardingLanding.takesAbout({ min: 3 }) }}</MkInfo>
</div>
</MkSpacer>