feat(frontend): タイムライン紹介を追加

This commit is contained in:
NoriDev 2023-08-23 17:43:30 +09:00
parent 9e90b8ba13
commit 80022cb991
8 changed files with 137 additions and 3 deletions

View file

@ -31,6 +31,7 @@
- 노트의 리액션을 삭제하지 않고도 리액션 버튼을 눌러 리액션을 변경할 수 있도록 (misskey-dev/misskey#11157)
- 리노트를 신고할 수 있도록 (misskey-dev/misskey#11466)
- Rosé Pine 테마 추가 ([rose-pine/misskey](https://github.com/rose-pine/misskey))
- 타임라인 소개 추가
### Client
- about-misskey 페이지에서 클라이언트 버전을 누르면 변경 사항을 볼 수 있음

View file

@ -1168,6 +1168,13 @@ additionalPermissionsForFlash: "Allow to add permission to Play"
thisFlashRequiresTheFollowingPermissions: "This Play requires the following permissions"
doYouWantToAllowThisPlayToAccessYourAccount: "Do you want to allow this Play to access your account?"
translateProfile: "Translate profile"
_tlTutorial:
step1_1: 'The {icon} Home timeline is where you can see posts from the accounts you follow.'
step1_2: 'The {icon} Local timeline is where you can see posts from everyone else on this server.'
step1_3: 'The {icon} Media timeline is where you can see posts from everyone else on this server, but only those that contain media(photos, videos).'
step1_4: 'The {icon} Social timeline is a combination of the Home and Local timelines.'
step1_5: 'The {icon} Cat timeline shows posts from users who have enabled cat on this server and every other connected server.'
step1_6: 'The {icon} Global timeline is where you can see posts from every other connected server.'
_announcement:
forExistingUsers: "Existing users only"
forExistingUsersDescription: "This announcement will only be shown to users existing at the point of publishment if enabled. If disabled, those newly signing up after it has been posted will also see it."

8
locales/index.d.ts vendored
View file

@ -1171,6 +1171,14 @@ export interface Locale {
"thisFlashRequiresTheFollowingPermissions": string;
"doYouWantToAllowThisPlayToAccessYourAccount": string;
"translateProfile": string;
"_tlTutorial": {
"step1_1": string;
"step1_2": string;
"step1_3": string;
"step1_4": string;
"step1_5": string;
"step1_6": string;
};
"_announcement": {
"forExistingUsers": string;
"forExistingUsersDescription": string;

View file

@ -1169,6 +1169,14 @@ thisFlashRequiresTheFollowingPermissions: "このPlayは以下の権限を要求
doYouWantToAllowThisPlayToAccessYourAccount: "このPlayによるアカウントへのアクセスを許可しますか"
translateProfile: "プロフィールを翻訳する"
_tlTutorial:
step1_1: '{icon} ホームタイムラインは、あなたがフォローしているアカウントの投稿を見られます。'
step1_2: '{icon} ローカルタイムラインでは、このサーバーにいるみんなの投稿を見られます。'
step1_3: '{icon} メディアタイムラインは、このサーバーにいるみんなの投稿のうち、メディア(写真、動画)を含む投稿のみを見ることができます。'
step1_4: '{icon} ソーシャルタイムラインでは、ホームタイムラインとローカルタイムラインの投稿が両方表示されます。'
step1_5: '{icon} キャットタイムラインでは、このサーバーに接続されているすべてのサーバーのうち、キャットを有効にしたユーザーの投稿を見ることができます。'
step1_6: '{icon} グローバルタイムラインでは、このサーバーに接続されているすべてのサーバーからの投稿を見られます。'
_announcement:
forExistingUsers: "既存ユーザーのみ"
forExistingUsersDescription: "有効にすると、このお知らせ作成時点で存在するユーザーにのみお知らせが表示されます。無効にすると、このお知らせ作成後にアカウントを作成したユーザーにもお知らせが表示されます。"

View file

@ -1169,6 +1169,13 @@ additionalPermissionsForFlash: "Play에 대한 추가 권한"
thisFlashRequiresTheFollowingPermissions: "이 Play는 다음 권한을 요구해요"
doYouWantToAllowThisPlayToAccessYourAccount: "이 Play가 계정에 접근하도록 허용할까요?"
translateProfile: "프로필 번역하기"
_tlTutorial:
step1_1: '{icon} 홈 타임라인은 내가 팔로우하고 있는 계정의 게시물을 볼 수 있어요.'
step1_2: '{icon} 로컬 타임라인은 이 서버의 모든 유저가 올린 게시물을 볼 수 있어요.'
step1_3: '{icon} 미디어 타임라인은 이 서버의 모든 유저가 올린 게시물 중, 미디어(사진, 영상)가 포함된 게시물만 볼 수 있어요.'
step1_4: '{icon} 소셜 타임라인은 홈 타임라인과 로컬 타임라인을 합친 것과 같아요.'
step1_5: '{icon} 고양이 타임라인에서는 이 서버와 연결된 모든 서버 중, 고양이를 활성화한 유저의 게시물을 볼 수 있어요.'
step1_6: '{icon} 글로벌 타임라인에서는 이 서버와 연결된 모든 서버의 게시물을 볼 수 있어요.'
_announcement:
forExistingUsers: "기존 유저에게만 알리기"
forExistingUsersDescription: "활성화하면 이 공지사항을 게시한 시점에서 이미 가입한 유저에게만 표시해요. 비활성화하면 게시 후에 가입한 유저에게도 표시해요."

View file

@ -4,19 +4,35 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div :class="[$style.root, { [$style.warn]: warn }]">
<div v-if="visible" :class="[$style.root, { [$style.warn]: warn }]">
<i v-if="warn" class="ti ti-alert-triangle" :class="$style.i"></i>
<i v-else class="ti ti-info-circle" :class="$style.i"></i>
<slot></slot>
<button v-if="closeable" v-tooltip="i18n.ts.close" :class="$style.close" class="_button" @click.stop="close" :aria-label="i18n.t('close')">
<i class="ti ti-x"></i>
</button>
</div>
</template>
<script lang="ts" setup>
import { } from 'vue';
import { ref } from 'vue';
import { i18n } from '@/i18n';
const visible = ref(true);
const props = defineProps<{
warn?: boolean;
closeable?: boolean;
}>();
const emit = defineEmits<{
(ev: 'closed'): void;
}>();
function close() {
visible.value = false;
emit('closed');
}
</script>
<style lang="scss" module>
@ -27,6 +43,8 @@ const props = defineProps<{
color: var(--infoFg);
border-radius: var(--radius);
white-space: pre-wrap;
display: flex;
align-items: center;
&.warn {
background: var(--infoWarnBg);
@ -35,6 +53,11 @@ const props = defineProps<{
}
.i {
margin-right: 4px;
margin-right: 8px;
}
.close {
margin-left: auto;
float: right;
}
</style>

View file

@ -4,6 +4,9 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<MkInfo v-if="tlHint && !tlHintClosed" :closeable="true" style="margin-bottom: 16px;" @close="closeHint">
<I18n :src="tlHint"><template #icon><i :class="tlIcon"></i></template></I18n>
</MkInfo>
<MkNotes ref="tlComponent" :noGap="!defaultStore.state.showGapBetweenNotesInTimeline" :pagination="pagination" @queue="emit('queue', $event)"/>
</template>
@ -14,6 +17,8 @@ import { useStream } from '@/stream';
import * as sound from '@/scripts/sound';
import { $i } from '@/account';
import { defaultStore } from '@/store';
import MkInfo from '@/components/MkInfo.vue';
import { i18n } from '@/i18n';
const props = defineProps<{
src: string;
@ -60,6 +65,10 @@ let query;
let connection;
let connection2;
let tlIcon;
let tlHint;
let tlHintClosed;
const stream = useStream();
if (props.src === 'antenna') {
@ -82,6 +91,10 @@ if (props.src === 'antenna') {
connection.on('note', prepend);
connection2 = stream.useChannel('main');
tlIcon = 'ti ti-home';
tlHint = i18n.ts._tlTutorial.step1_1;
tlHintClosed = defaultStore.state.tlHomeHintClosed;
} else if (props.src === 'local') {
endpoint = 'notes/local-timeline';
query = {
@ -91,10 +104,18 @@ if (props.src === 'antenna') {
withReplies: defaultStore.state.showTimelineReplies,
});
connection.on('note', prepend);
tlIcon = 'ti ti-planet';
tlHint = i18n.ts._tlTutorial.step1_2;
tlHintClosed = defaultStore.state.tlLocalHintClosed;
} else if (props.src === 'media') {
endpoint = 'notes/media-timeline';
connection = stream.useChannel('mediaTimeline');
connection.on('note', prependFilterdMedia);
tlIcon = 'ti ti-photo';
tlHint = i18n.ts._tlTutorial.step1_3;
tlHintClosed = defaultStore.state.tlMediaHintClosed;
} else if (props.src === 'social') {
endpoint = 'notes/hybrid-timeline';
query = {
@ -104,6 +125,10 @@ if (props.src === 'antenna') {
withReplies: defaultStore.state.showTimelineReplies,
});
connection.on('note', prepend);
tlIcon = 'ti ti-rocket';
tlHint = i18n.ts._tlTutorial.step1_4;
tlHintClosed = defaultStore.state.tlSocialHintClosed;
} else if (props.src === 'cat') {
endpoint = 'notes/cat-timeline';
query = {
@ -113,6 +138,10 @@ if (props.src === 'antenna') {
withReplies: defaultStore.state.showTimelineReplies,
});
connection.on('note', prepend);
tlIcon = 'ti ti-cat';
tlHint = i18n.ts._tlTutorial.step1_5;
tlHintClosed = defaultStore.state.tlCatHintClosed;
} else if (props.src === 'global') {
endpoint = 'notes/global-timeline';
query = {
@ -122,6 +151,10 @@ if (props.src === 'antenna') {
withReplies: defaultStore.state.showTimelineReplies,
});
connection.on('note', prepend);
tlIcon = 'ti ti-world';
tlHint = i18n.ts._tlTutorial.step1_6;
tlHintClosed = defaultStore.state.tlGlobalHintClosed;
} else if (props.src === 'mentions') {
endpoint = 'notes/mentions';
connection = stream.useChannel('main');
@ -167,6 +200,29 @@ if (props.src === 'antenna') {
connection.on('note', prepend);
}
function closeHint() {
switch (props.src) {
case "home":
defaultStore.set("tlHomeHintClosed", true);
break;
case "local":
defaultStore.set("tlLocalHintClosed", true);
break;
case "media":
defaultStore.set("tlMediaHintClosed", true);
break;
case "social":
defaultStore.set("tlSocialHintClosed", true);
break;
case "cat":
defaultStore.set("tlCatHintClosed", true);
break;
case "global":
defaultStore.set("tlGlobalHintClosed", true);
break;
}
}
const pagination = {
endpoint: endpoint,
limit: 10,

View file

@ -51,6 +51,30 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'account',
default: 0,
},
tlHomeHintClosed: {
where: "device",
default: false,
},
tlLocalHintClosed: {
where: "device",
default: false,
},
tlMediaHintClosed: {
where: "device",
default: false,
},
tlSocialHintClosed: {
where: "device",
default: false,
},
tlCatHintClosed: {
where: "device",
default: false,
},
tlGlobalHintClosed: {
where: "device",
default: false,
},
keepCw: {
where: 'account',
default: true,