mirror of
https://github.com/kokonect-link/cherrypick
synced 2024-11-27 14:28:53 +09:00
feat: メディアタイムラインを改善
This commit is contained in:
parent
5e02db855e
commit
9598552367
@ -31,6 +31,7 @@
|
||||
- 제어판 메인 화면에 서버 통계 추가
|
||||
- 노트의 시간을 일자로 표시하는 기능
|
||||
- 고양이 타임라인 추가
|
||||
- 미디어 타임라인 개선
|
||||
|
||||
### Client
|
||||
- 리노트 전 확인 팝업을 띄움
|
||||
@ -42,6 +43,9 @@
|
||||
- Fix: 프로필 아이콘이 투명일 때 노트 답글선이 비치는 문제
|
||||
- Fix: 서브 노트의 내용 숨김 버튼의 디자인이 잘못 표시되는 문제
|
||||
|
||||
### Server
|
||||
- 미디어 타임라인 개선
|
||||
|
||||
---
|
||||
|
||||
## 13.13.2-cp-4.1.0
|
||||
|
@ -1484,6 +1484,7 @@ _role:
|
||||
_options:
|
||||
gtlAvailable: "Can view the global timeline"
|
||||
ltlAvailable: "Can view the local timeline"
|
||||
mtlAvailable: "Can view the media timeline"
|
||||
ctlAvailable: "Can view the cat timeline"
|
||||
canPublicNote: "Can send public notes"
|
||||
canInvite: "Can create instance invite codes"
|
||||
|
1
locales/index.d.ts
vendored
1
locales/index.d.ts
vendored
@ -1572,6 +1572,7 @@ export interface Locale {
|
||||
"_options": {
|
||||
"gtlAvailable": string;
|
||||
"ltlAvailable": string;
|
||||
"mtlAvailable": string;
|
||||
"ctlAvailable": string;
|
||||
"canPublicNote": string;
|
||||
"canInvite": string;
|
||||
|
@ -1494,6 +1494,7 @@ _role:
|
||||
_options:
|
||||
gtlAvailable: "グローバルタイムラインの閲覧"
|
||||
ltlAvailable: "ローカルタイムラインの閲覧"
|
||||
mtlAvailable: "メディアタイムラインの閲覧"
|
||||
ctlAvailable: "キャットタイムラインの閲覧"
|
||||
canPublicNote: "パブリック投稿の許可"
|
||||
canInvite: "サーバー招待コードの発行"
|
||||
|
@ -1484,6 +1484,7 @@ _role:
|
||||
_options:
|
||||
gtlAvailable: "글로벌 타임라인 보이기"
|
||||
ltlAvailable: "로컬 타임라인 보이기"
|
||||
mtlAvailable: "미디어 타임라인 보이기"
|
||||
ctlAvailable: "고양이 타임라인 보이기"
|
||||
canPublicNote: "공개 노트 허용"
|
||||
canInvite: "서버 초대 코드 발행"
|
||||
|
@ -19,6 +19,7 @@ import type { OnApplicationShutdown } from '@nestjs/common';
|
||||
export type RolePolicies = {
|
||||
gtlAvailable: boolean;
|
||||
ltlAvailable: boolean;
|
||||
mtlAvailable: boolean;
|
||||
ctlAvailable: boolean;
|
||||
canPublicNote: boolean;
|
||||
canInvite: boolean;
|
||||
@ -41,6 +42,7 @@ export type RolePolicies = {
|
||||
export const DEFAULT_POLICIES: RolePolicies = {
|
||||
gtlAvailable: true,
|
||||
ltlAvailable: true,
|
||||
mtlAvailable: true,
|
||||
ctlAvailable: true,
|
||||
canPublicNote: true,
|
||||
canInvite: false,
|
||||
@ -277,6 +279,7 @@ export class RoleService implements OnApplicationShutdown {
|
||||
return {
|
||||
gtlAvailable: calc('gtlAvailable', vs => vs.some(v => v === true)),
|
||||
ltlAvailable: calc('ltlAvailable', vs => vs.some(v => v === true)),
|
||||
mtlAvailable: calc('mtlAvailable', vs => vs.some(v => v === true)),
|
||||
ctlAvailable: calc('ctlAvailable', vs => vs.some(v => v === true)),
|
||||
canPublicNote: calc('canPublicNote', vs => vs.some(v => v === true)),
|
||||
canInvite: calc('canInvite', vs => vs.some(v => v === true)),
|
||||
|
@ -105,6 +105,7 @@ export class NodeinfoServerService {
|
||||
feedbackUrl: meta.feedbackUrl,
|
||||
disableRegistration: meta.disableRegistration,
|
||||
disableLocalTimeline: !basePolicies.ltlAvailable,
|
||||
disableMediaTimeline: !basePolicies.mtlAvailable,
|
||||
disableCatTimeline: !basePolicies.ctlAvailable,
|
||||
disableGlobalTimeline: !basePolicies.gtlAvailable,
|
||||
emailRequiredForSignup: meta.emailRequiredForSignup,
|
||||
|
@ -25,7 +25,7 @@ export const meta = {
|
||||
},
|
||||
|
||||
errors: {
|
||||
ltlDisabled: {
|
||||
mtlDisabled: {
|
||||
message: 'Media timeline has been disabled.',
|
||||
code: 'MTL_DISABLED',
|
||||
id: '45a6eb02-7695-4393-b023-dd4be9aaaefd',
|
||||
@ -71,8 +71,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const policies = await this.roleService.getUserPolicies(me ? me.id : null);
|
||||
if (!policies.ltlAvailable) {
|
||||
throw new ApiError(meta.errors.ltlDisabled);
|
||||
if (!policies.mtlAvailable) {
|
||||
throw new ApiError(meta.errors.mtlDisabled);
|
||||
}
|
||||
|
||||
//#region Construct query
|
||||
|
@ -29,7 +29,7 @@ class MediaTimelineChannel extends Channel {
|
||||
@bindThis
|
||||
public async init(params: any) {
|
||||
const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null);
|
||||
if (!policies.ltlAvailable) return;
|
||||
if (!policies.mtlAvailable) return;
|
||||
|
||||
this.withReplies = params.withReplies as boolean;
|
||||
|
||||
|
@ -55,6 +55,7 @@ export const obsoleteNotificationTypes = ['pollVote'/*, 'groupInvited'*/] as con
|
||||
export const ROLE_POLICIES = [
|
||||
'gtlAvailable',
|
||||
'ltlAvailable',
|
||||
'mtlAvailable',
|
||||
'ctlAvailable',
|
||||
'canPublicNote',
|
||||
'canInvite',
|
||||
|
@ -131,6 +131,26 @@
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.mtlAvailable, 'mtlAvailable'])">
|
||||
<template #label>{{ i18n.ts._role._options.mtlAvailable }}</template>
|
||||
<template #suffix>
|
||||
<span v-if="role.policies.mtlAvailable.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||
<span v-else>{{ role.policies.mtlAvailable.value ? i18n.ts.yes : i18n.ts.no }}</span>
|
||||
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.mtlAvailable)"></i></span>
|
||||
</template>
|
||||
<div class="_gaps">
|
||||
<MkSwitch v-model="role.policies.mtlAvailable.useDefault" :readonly="readonly">
|
||||
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||
</MkSwitch>
|
||||
<MkSwitch v-model="role.policies.mtlAvailable.value" :disabled="role.policies.mtlAvailable.useDefault" :readonly="readonly">
|
||||
<template #label>{{ i18n.ts.enable }}</template>
|
||||
</MkSwitch>
|
||||
<MkRange v-model="role.policies.mtlAvailable.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
|
||||
<template #label>{{ i18n.ts._role.priority }}</template>
|
||||
</MkRange>
|
||||
</div>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.ctlAvailable, 'ctlAvailable'])">
|
||||
<template #label>{{ i18n.ts._role._options.ctlAvailable }}</template>
|
||||
<template #suffix>
|
||||
|
@ -35,6 +35,14 @@
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.mtlAvailable, 'mtlAvailable'])">
|
||||
<template #label>{{ i18n.ts._role._options.mtlAvailable }}</template>
|
||||
<template #suffix>{{ policies.mtlAvailable ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
<MkSwitch v-model="policies.mtlAvailable">
|
||||
<template #label>{{ i18n.ts.enable }}</template>
|
||||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.ctlAvailable, 'ctlAvailable'])">
|
||||
<template #label>{{ i18n.ts._role._options.ctlAvailable }}</template>
|
||||
<template #suffix>{{ policies.ctlAvailable ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
|
@ -72,6 +72,7 @@ const XTutorial = defineAsyncComponent(() => import('./timeline.tutorial.vue'));
|
||||
|
||||
const isLocalTimelineAvailable = ($i == null && instance.policies.ltlAvailable) || ($i != null && $i.policies.ltlAvailable);
|
||||
const isGlobalTimelineAvailable = ($i == null && instance.policies.gtlAvailable) || ($i != null && $i.policies.gtlAvailable);
|
||||
const isMediaTimelineAvailable = ($i == null && instance.policies.mtlAvailable) || ($i != null && $i.policies.mtlAvailable);
|
||||
const isCatTimelineAvailable = ($i == null && instance.policies.ctlAvailable) || ($i != null && $i.policies.ctlAvailable);
|
||||
const keymap = {
|
||||
't': focus,
|
||||
@ -192,12 +193,12 @@ const headerTabs = $computed(() => [{
|
||||
title: i18n.ts._timelines.local,
|
||||
icon: 'ti ti-planet',
|
||||
iconOnly: true,
|
||||
}, {
|
||||
}, ...(isMediaTimelineAvailable ? [{
|
||||
key: 'media',
|
||||
title: i18n.ts._timelines.media,
|
||||
icon: 'ti ti-photo',
|
||||
iconOnly: true,
|
||||
}, {
|
||||
}] : []), {
|
||||
key: 'social',
|
||||
title: i18n.ts._timelines.social,
|
||||
icon: 'ti ti-rocket',
|
||||
@ -207,7 +208,7 @@ const headerTabs = $computed(() => [{
|
||||
title: i18n.ts._timelines.cat,
|
||||
icon: 'ti ti-cat',
|
||||
iconOnly: true,
|
||||
}] : []), ] : []), ...(isGlobalTimelineAvailable ? [{
|
||||
}] : [])] : []), ...(isGlobalTimelineAvailable ? [{
|
||||
key: 'global',
|
||||
title: i18n.ts._timelines.global,
|
||||
icon: 'ti ti-world',
|
||||
|
@ -3,14 +3,14 @@
|
||||
<template #header>
|
||||
<i v-if="column.tl === 'home'" class="ti ti-home"></i>
|
||||
<i v-else-if="column.tl === 'local'" class="ti ti-planet"></i>
|
||||
<i v-else-if="column.tl === 'social'" class="ti ti-rocket"></i>
|
||||
<i v-else-if="column.tl === 'media'" class="ti ti-photo"></i>
|
||||
<i v-else-if="column.tl === 'social'" class="ti ti-rocket"></i>
|
||||
<i v-else-if="column.tl === 'cat'" class="ti cat"></i>
|
||||
<i v-else-if="column.tl === 'global'" class="ti ti-world"></i>
|
||||
<span style="margin-left: 8px;">{{ column.name }}</span>
|
||||
</template>
|
||||
|
||||
<div v-if="(((column.tl === 'local' || column.tl === 'social' || column.tl === 'cat') && !isLocalTimelineAvailable) || (column.tl === 'cat' && !isCatTimelineAvailable) || (column.tl === 'global' && !isGlobalTimelineAvailable))" :class="$style.disabled">
|
||||
<div v-if="(((column.tl === 'local' || column.tl === 'social' || column.tl === 'media' || column.tl === 'cat') && !isLocalTimelineAvailable) || (column.tl === 'media' && !isMediaTimelineAvailable) || (column.tl === 'cat' && !isCatTimelineAvailable) || (column.tl === 'global' && !isGlobalTimelineAvailable))" :class="$style.disabled">
|
||||
<p :class="$style.disabledTitle">
|
||||
<i class="ti ti-circle-minus"></i>
|
||||
{{ i18n.ts._disabledTimeline.title }}
|
||||
@ -40,6 +40,7 @@ let disabled = $ref(false);
|
||||
|
||||
const isLocalTimelineAvailable = (($i == null && instance.policies.ltlAvailable) || ($i != null && $i.policies.ltlAvailable));
|
||||
const isGlobalTimelineAvailable = (($i == null && instance.policies.gtlAvailable) || ($i != null && $i.policies.gtlAvailable));
|
||||
const isMediaTimelineAvailable = (($i == null && instance.policies.mtlAvailable) || ($i != null && $i.policies.mtlAvailable));
|
||||
const isCatTimelineAvailable = (($i == null && instance.policies.ctlAvailable) || ($i != null && $i.policies.ctlAvailable));
|
||||
|
||||
onMounted(() => {
|
||||
@ -47,7 +48,8 @@ onMounted(() => {
|
||||
setType();
|
||||
} else if ($i) {
|
||||
disabled = (
|
||||
(!((instance.policies.ltlAvailable) || ($i.policies.ltlAvailable)) && ['local', 'social', 'cat'].includes(props.column.tl)) ||
|
||||
(!((instance.policies.ltlAvailable) || ($i.policies.ltlAvailable)) && ['local', 'social', 'media', 'cat'].includes(props.column.tl)) ||
|
||||
(!((instance.policies.mtlAvailable) || ($i.policies.mtlAvailable)) && ['media'].includes(props.column.tl)) ||
|
||||
(!((instance.policies.ctlAvailable) || ($i.policies.ctlAvailable)) && ['cat'].includes(props.column.tl)) ||
|
||||
(!((instance.policies.gtlAvailable) || ($i.policies.gtlAvailable)) && ['global'].includes(props.column.tl)));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
<template #icon>
|
||||
<i v-if="widgetProps.src === 'home'" class="ti ti-home"></i>
|
||||
<i v-else-if="widgetProps.src === 'local'" class="ti ti-planet"></i>
|
||||
<i v-else-if="widgetProps.src === 'media'" class="ti ti-photo"></i>
|
||||
<i v-else-if="widgetProps.src === 'social'" class="ti ti-rocket"></i>
|
||||
<i v-else-if="widgetProps.src === 'cat'" class="ti ti-cat"></i>
|
||||
<i v-else-if="widgetProps.src === 'global'" class="ti ti-world"></i>
|
||||
@ -16,7 +17,7 @@
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<div v-if="(((widgetProps.src === 'local' || widgetProps.src === 'social' || widgetProps.src === 'cat') && !isLocalTimelineAvailable) || (widgetProps.src === 'cat' && !isCatTimelineAvailable) || (widgetProps.src === 'global' && !isGlobalTimelineAvailable))" :class="$style.disabled">
|
||||
<div v-if="(((widgetProps.src === 'local' || widgetProps.src === 'social' || widgetProps.src === 'media' || widgetProps.src === 'cat') && !isLocalTimelineAvailable) || (widgetProps.src === 'media' && !isMediaTimelineAvailable) || (widgetProps.src === 'cat' && !isCatTimelineAvailable) || (widgetProps.src === 'global' && !isGlobalTimelineAvailable))" :class="$style.disabled">
|
||||
<p :class="$style.disabledTitle">
|
||||
<i class="ti ti-minus"></i>
|
||||
{{ i18n.ts._disabledTimeline.title }}
|
||||
@ -43,6 +44,7 @@ import { instance } from '@/instance';
|
||||
const name = 'timeline';
|
||||
const isLocalTimelineAvailable = (($i == null && instance.policies.ltlAvailable) || ($i != null && $i.policies.ltlAvailable));
|
||||
const isGlobalTimelineAvailable = (($i == null && instance.policies.gtlAvailable) || ($i != null && $i.policies.gtlAvailable));
|
||||
const isMediaTimelineAvailable = (($i == null && instance.policies.mtlAvailable) || ($i != null && $i.policies.mtlAvailable));
|
||||
const isCatTimelineAvailable = (($i == null && instance.policies.ctlAvailable) || ($i != null && $i.policies.ctlAvailable));
|
||||
|
||||
const widgetPropsDef = {
|
||||
|
Loading…
Reference in New Issue
Block a user