Compare commits
8 Commits
7a41cfe28b
...
d91a4e3dec
Author | SHA1 | Date |
---|---|---|
|
d91a4e3dec | |
|
6a69e4180b | |
|
3b3bb36c49 | |
|
69cfd34545 | |
|
9481b5a6e8 | |
|
effc84b9cc | |
|
de073d6d69 | |
|
5042a0aa8f |
|
@ -15,11 +15,7 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
# Chromatic is not likely to be available for fork repositories, so we disable for fork repositories.
|
# Chromatic is not likely to be available for fork repositories, so we disable for fork repositories.
|
||||||
# Neither Dependabot nor Renovate will change the actual behavior for components.
|
if: github.repository == 'misskey-dev/misskey'
|
||||||
if: >-
|
|
||||||
github.repository == 'misskey-dev/misskey' &&
|
|
||||||
startsWith(github.head_ref, 'refs/heads/dependabot/') != true &&
|
|
||||||
startsWith(github.head_ref, 'refs/heads/renovate/') != true
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
### General
|
### General
|
||||||
- Feat: bull-boardに代わるジョブキューの管理ツールが実装されました
|
- Feat: bull-boardに代わるジョブキューの管理ツールが実装されました
|
||||||
|
- Feat: アップロード可能な最大ファイルサイズをロールごとに設定可能に
|
||||||
|
- デフォルトで10MBになっています
|
||||||
- Enhance: チャットの新規メッセージをプッシュ通知するように
|
- Enhance: チャットの新規メッセージをプッシュ通知するように
|
||||||
|
|
||||||
### Client
|
### Client
|
||||||
|
@ -17,6 +19,7 @@
|
||||||
- Fix: タイムラインのスクロール位置を記憶するように修正
|
- Fix: タイムラインのスクロール位置を記憶するように修正
|
||||||
- Fix: ノートの直後のノートを表示する機能で表示が逆順になっていた問題を修正 #15841
|
- Fix: ノートの直後のノートを表示する機能で表示が逆順になっていた問題を修正 #15841
|
||||||
- Fix: アカウントの移行時にアンテナのフィルターのユーザが更新されない問題を修正 #15843
|
- Fix: アカウントの移行時にアンテナのフィルターのユーザが更新されない問題を修正 #15843
|
||||||
|
- Fix: タイムラインでノートが重複して表示されることがあるのを修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- Enhance: ジョブキューの成功/失敗したジョブも一定数・一定期間保存するようにし、後から問題を調査することを容易に
|
- Enhance: ジョブキューの成功/失敗したジョブも一定数・一定期間保存するようにし、後から問題を調査することを容易に
|
||||||
|
|
|
@ -7464,6 +7464,10 @@ export interface Locale extends ILocale {
|
||||||
* ドライブ容量
|
* ドライブ容量
|
||||||
*/
|
*/
|
||||||
"driveCapacity": string;
|
"driveCapacity": string;
|
||||||
|
/**
|
||||||
|
* アップロード可能な最大ファイルサイズ
|
||||||
|
*/
|
||||||
|
"maxFileSize": string;
|
||||||
/**
|
/**
|
||||||
* ファイルにNSFWを常に付与
|
* ファイルにNSFWを常に付与
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1934,6 +1934,7 @@ _role:
|
||||||
canManageCustomEmojis: "カスタム絵文字の管理"
|
canManageCustomEmojis: "カスタム絵文字の管理"
|
||||||
canManageAvatarDecorations: "アバターデコレーションの管理"
|
canManageAvatarDecorations: "アバターデコレーションの管理"
|
||||||
driveCapacity: "ドライブ容量"
|
driveCapacity: "ドライブ容量"
|
||||||
|
maxFileSize: "アップロード可能な最大ファイルサイズ"
|
||||||
alwaysMarkNsfw: "ファイルにNSFWを常に付与"
|
alwaysMarkNsfw: "ファイルにNSFWを常に付与"
|
||||||
canUpdateBioMedia: "アイコンとバナーの更新を許可"
|
canUpdateBioMedia: "アイコンとバナーの更新を許可"
|
||||||
pinMax: "ノートのピン留めの最大数"
|
pinMax: "ノートのピン留めの最大数"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "2025.4.1-alpha.2",
|
"version": "2025.4.1-beta.0",
|
||||||
"codename": "nasubi",
|
"codename": "nasubi",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -522,9 +522,16 @@ export class DriveService {
|
||||||
|
|
||||||
const policies = await this.roleService.getUserPolicies(user.id);
|
const policies = await this.roleService.getUserPolicies(user.id);
|
||||||
const driveCapacity = 1024 * 1024 * policies.driveCapacityMb;
|
const driveCapacity = 1024 * 1024 * policies.driveCapacityMb;
|
||||||
|
const maxFileSize = 1024 * 1024 * policies.maxFileSizeMb;
|
||||||
this.registerLogger.debug('drive capacity override applied');
|
this.registerLogger.debug('drive capacity override applied');
|
||||||
this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`);
|
this.registerLogger.debug(`overrideCap: ${driveCapacity}bytes, usage: ${usage}bytes, u+s: ${usage + info.size}bytes`);
|
||||||
|
|
||||||
|
if (maxFileSize < info.size) {
|
||||||
|
if (isLocalUser) {
|
||||||
|
throw new IdentifiableError('f9e4e5f3-4df4-40b5-b400-f236945f7073', 'Max file size exceeded.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If usage limit exceeded
|
// If usage limit exceeded
|
||||||
if (driveCapacity < usage + info.size) {
|
if (driveCapacity < usage + info.size) {
|
||||||
if (isLocalUser) {
|
if (isLocalUser) {
|
||||||
|
|
|
@ -34,6 +34,7 @@ export const webpDefault: sharp.WebpOptions = {
|
||||||
smartSubsample: true,
|
smartSubsample: true,
|
||||||
mixed: true,
|
mixed: true,
|
||||||
effort: 2,
|
effort: 2,
|
||||||
|
loop: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const avifDefault: sharp.AvifOptions = {
|
export const avifDefault: sharp.AvifOptions = {
|
||||||
|
|
|
@ -46,6 +46,7 @@ export type RolePolicies = {
|
||||||
canUseTranslator: boolean;
|
canUseTranslator: boolean;
|
||||||
canHideAds: boolean;
|
canHideAds: boolean;
|
||||||
driveCapacityMb: number;
|
driveCapacityMb: number;
|
||||||
|
maxFileSizeMb: number;
|
||||||
alwaysMarkNsfw: boolean;
|
alwaysMarkNsfw: boolean;
|
||||||
canUpdateBioMedia: boolean;
|
canUpdateBioMedia: boolean;
|
||||||
pinLimit: number;
|
pinLimit: number;
|
||||||
|
@ -81,6 +82,7 @@ export const DEFAULT_POLICIES: RolePolicies = {
|
||||||
canUseTranslator: true,
|
canUseTranslator: true,
|
||||||
canHideAds: false,
|
canHideAds: false,
|
||||||
driveCapacityMb: 100,
|
driveCapacityMb: 100,
|
||||||
|
maxFileSizeMb: 10,
|
||||||
alwaysMarkNsfw: false,
|
alwaysMarkNsfw: false,
|
||||||
canUpdateBioMedia: true,
|
canUpdateBioMedia: true,
|
||||||
pinLimit: 5,
|
pinLimit: 5,
|
||||||
|
@ -391,6 +393,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit {
|
||||||
canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)),
|
canUseTranslator: calc('canUseTranslator', vs => vs.some(v => v === true)),
|
||||||
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
|
canHideAds: calc('canHideAds', vs => vs.some(v => v === true)),
|
||||||
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
|
driveCapacityMb: calc('driveCapacityMb', vs => Math.max(...vs)),
|
||||||
|
maxFileSizeMb: calc('maxFileSizeMb', vs => Math.max(...vs)),
|
||||||
alwaysMarkNsfw: calc('alwaysMarkNsfw', vs => vs.some(v => v === true)),
|
alwaysMarkNsfw: calc('alwaysMarkNsfw', vs => vs.some(v => v === true)),
|
||||||
canUpdateBioMedia: calc('canUpdateBioMedia', vs => vs.some(v => v === true)),
|
canUpdateBioMedia: calc('canUpdateBioMedia', vs => vs.some(v => v === true)),
|
||||||
pinLimit: calc('pinLimit', vs => Math.max(...vs)),
|
pinLimit: calc('pinLimit', vs => Math.max(...vs)),
|
||||||
|
|
|
@ -224,6 +224,10 @@ export const packedRolePoliciesSchema = {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
|
maxFileSizeMb: {
|
||||||
|
type: 'integer',
|
||||||
|
optional: false, nullable: false,
|
||||||
|
},
|
||||||
alwaysMarkNsfw: {
|
alwaysMarkNsfw: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
|
|
|
@ -10,9 +10,9 @@ import { IdentifiableError } from '@/misc/identifiable-error.js';
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
|
||||||
import { DriveService } from '@/core/DriveService.js';
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { ApiError } from '../../../error.js';
|
|
||||||
import { MiMeta } from '@/models/_.js';
|
import { MiMeta } from '@/models/_.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
|
import { ApiError } from '../../../error.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['drive'],
|
tags: ['drive'],
|
||||||
|
@ -56,6 +56,12 @@ export const meta = {
|
||||||
code: 'NO_FREE_SPACE',
|
code: 'NO_FREE_SPACE',
|
||||||
id: 'd08dbc37-a6a9-463a-8c47-96c32ab5f064',
|
id: 'd08dbc37-a6a9-463a-8c47-96c32ab5f064',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
maxFileSizeExceeded: {
|
||||||
|
message: 'Cannot upload the file because it exceeds the maximum file size.',
|
||||||
|
code: 'MAX_FILE_SIZE_EXCEEDED',
|
||||||
|
id: 'b9d8c348-33f0-4673-b9a9-5d4da058977a',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
@ -115,6 +121,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
if (err instanceof IdentifiableError) {
|
if (err instanceof IdentifiableError) {
|
||||||
if (err.id === '282f77bf-5816-4f72-9264-aa14d8261a21') throw new ApiError(meta.errors.inappropriate);
|
if (err.id === '282f77bf-5816-4f72-9264-aa14d8261a21') throw new ApiError(meta.errors.inappropriate);
|
||||||
if (err.id === 'c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6') throw new ApiError(meta.errors.noFreeSpace);
|
if (err.id === 'c6244ed2-a39a-4e1c-bf93-f0fbd7764fa6') throw new ApiError(meta.errors.noFreeSpace);
|
||||||
|
if (err.id === 'f9e4e5f3-4df4-40b5-b400-f236945f7073') throw new ApiError(meta.errors.maxFileSizeExceeded);
|
||||||
}
|
}
|
||||||
throw new ApiError();
|
throw new ApiError();
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -91,6 +91,7 @@ export const ROLE_POLICIES = [
|
||||||
'canUseTranslator',
|
'canUseTranslator',
|
||||||
'canHideAds',
|
'canHideAds',
|
||||||
'driveCapacityMb',
|
'driveCapacityMb',
|
||||||
|
'maxFileSizeMb',
|
||||||
'alwaysMarkNsfw',
|
'alwaysMarkNsfw',
|
||||||
'canUpdateBioMedia',
|
'canUpdateBioMedia',
|
||||||
'pinLimit',
|
'pinLimit',
|
||||||
|
|
|
@ -55,7 +55,7 @@ await fs.readFile(
|
||||||
'../../locales/ja-JP.yml',
|
'../../locales/ja-JP.yml',
|
||||||
'assets/**',
|
'assets/**',
|
||||||
'public/**',
|
'public/**',
|
||||||
'../../pnpm-lock.yaml',
|
'package.json',
|
||||||
]).length
|
]).length
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkAd :preferForms="['horizontal', 'horizontal-big']"/>
|
<MkAd :preferForms="['horizontal', 'horizontal-big']"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MkNote :class="$style.note" :note="note" :withHardMute="true" :data-scroll-anchor="note.id"/>
|
<MkNote v-else :class="$style.note" :note="note" :withHardMute="true" :data-scroll-anchor="note.id"/>
|
||||||
</template>
|
</template>
|
||||||
</component>
|
</component>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -40,19 +40,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts">
|
||||||
import { onMounted, onUnmounted, ref, inject, useTemplateRef, computed } from 'vue';
|
|
||||||
import { scrollToTop } from '@@/js/scroll.js';
|
|
||||||
import XTabs from './MkPageHeader.tabs.vue';
|
|
||||||
import type { Tab } from './MkPageHeader.tabs.vue';
|
|
||||||
import type { PageHeaderItem } from '@/types/page-header.js';
|
import type { PageHeaderItem } from '@/types/page-header.js';
|
||||||
import type { PageMetadata } from '@/page.js';
|
import type { PageMetadata } from '@/page.js';
|
||||||
import { globalEvents } from '@/events.js';
|
import type { Tab } from './MkPageHeader.tabs.vue';
|
||||||
import { openAccountMenu as openAccountMenu_ } from '@/accounts.js';
|
|
||||||
import { $i } from '@/i.js';
|
|
||||||
import { DI } from '@/di.js';
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
export type PageHeaderProps = {
|
||||||
overridePageMetadata?: PageMetadata;
|
overridePageMetadata?: PageMetadata;
|
||||||
tabs?: Tab[];
|
tabs?: Tab[];
|
||||||
tab?: string;
|
tab?: string;
|
||||||
|
@ -60,7 +53,19 @@ const props = withDefaults(defineProps<{
|
||||||
thin?: boolean;
|
thin?: boolean;
|
||||||
hideTitle?: boolean;
|
hideTitle?: boolean;
|
||||||
displayMyAvatar?: boolean;
|
displayMyAvatar?: boolean;
|
||||||
}>(), {
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, onUnmounted, ref, inject, useTemplateRef, computed } from 'vue';
|
||||||
|
import { scrollToTop } from '@@/js/scroll.js';
|
||||||
|
import XTabs from './MkPageHeader.tabs.vue';
|
||||||
|
import { globalEvents } from '@/events.js';
|
||||||
|
import { openAccountMenu as openAccountMenu_ } from '@/accounts.js';
|
||||||
|
import { $i } from '@/i.js';
|
||||||
|
import { DI } from '@/di.js';
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<PageHeaderProps>(), {
|
||||||
tabs: () => ([] as Tab[]),
|
tabs: () => ([] as Tab[]),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template>
|
<template>
|
||||||
<div ref="rootEl" :class="[$style.root, reversed ? '_pageScrollableReversed' : '_pageScrollable']">
|
<div ref="rootEl" :class="[$style.root, reversed ? '_pageScrollableReversed' : '_pageScrollable']">
|
||||||
<MkStickyContainer>
|
<MkStickyContainer>
|
||||||
<template #header><MkPageHeader v-model:tab="tab" :actions="actions" :tabs="tabs"/></template>
|
<template #header><MkPageHeader v-model:tab="tab" v-bind="pageHeaderProps"/></template>
|
||||||
<div :class="$style.body">
|
<div :class="$style.body">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,21 +16,18 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useTemplateRef } from 'vue';
|
import { computed, useTemplateRef } from 'vue';
|
||||||
import { scrollInContainer } from '@@/js/scroll.js';
|
import { scrollInContainer } from '@@/js/scroll.js';
|
||||||
import type { PageHeaderItem } from '@/types/page-header.js';
|
import type { PageHeaderProps } from './MkPageHeader.vue';
|
||||||
import type { Tab } from './MkPageHeader.tabs.vue';
|
|
||||||
import { useScrollPositionKeeper } from '@/use/use-scroll-position-keeper.js';
|
import { useScrollPositionKeeper } from '@/use/use-scroll-position-keeper.js';
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = defineProps<PageHeaderProps & {
|
||||||
tabs?: Tab[];
|
|
||||||
actions?: PageHeaderItem[] | null;
|
|
||||||
thin?: boolean;
|
|
||||||
hideTitle?: boolean;
|
|
||||||
displayMyAvatar?: boolean;
|
|
||||||
reversed?: boolean;
|
reversed?: boolean;
|
||||||
}>(), {
|
}>();
|
||||||
tabs: () => ([] as Tab[]),
|
|
||||||
|
const pageHeaderProps = computed(() => {
|
||||||
|
const { reversed, ...rest } = props;
|
||||||
|
return rest;
|
||||||
});
|
});
|
||||||
|
|
||||||
const tab = defineModel<string>('tab');
|
const tab = defineModel<string>('tab');
|
||||||
|
|
|
@ -386,6 +386,26 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.maxFileSize, 'maxFileSizeMb'])">
|
||||||
|
<template #label>{{ i18n.ts._role._options.maxFileSize }}</template>
|
||||||
|
<template #suffix>
|
||||||
|
<span v-if="role.policies.maxFileSizeMb.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
|
||||||
|
<span v-else>{{ role.policies.maxFileSizeMb.value + 'MB' }}</span>
|
||||||
|
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.maxFileSizeMb)"></i></span>
|
||||||
|
</template>
|
||||||
|
<div class="_gaps">
|
||||||
|
<MkSwitch v-model="role.policies.maxFileSizeMb.useDefault" :readonly="readonly">
|
||||||
|
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
|
||||||
|
</MkSwitch>
|
||||||
|
<MkInput v-model="role.policies.maxFileSizeMb.value" :disabled="role.policies.maxFileSizeMb.useDefault" type="number" :readonly="readonly">
|
||||||
|
<template #suffix>MB</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkRange v-model="role.policies.maxFileSizeMb.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.alwaysMarkNsfw, 'alwaysMarkNsfw'])">
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.alwaysMarkNsfw, 'alwaysMarkNsfw'])">
|
||||||
<template #label>{{ i18n.ts._role._options.alwaysMarkNsfw }}</template>
|
<template #label>{{ i18n.ts._role._options.alwaysMarkNsfw }}</template>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
|
|
|
@ -138,6 +138,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</MkInput>
|
</MkInput>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.maxFileSize, 'maxFileSizeMb'])">
|
||||||
|
<template #label>{{ i18n.ts._role._options.maxFileSize }}</template>
|
||||||
|
<template #suffix>{{ policies.maxFileSizeMb }}MB</template>
|
||||||
|
<MkInput v-model="policies.maxFileSizeMb" type="number">
|
||||||
|
<template #suffix>MB</template>
|
||||||
|
</MkInput>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.alwaysMarkNsfw, 'alwaysMarkNsfw'])">
|
<MkFolder v-if="matchQuery([i18n.ts._role._options.alwaysMarkNsfw, 'alwaysMarkNsfw'])">
|
||||||
<template #label>{{ i18n.ts._role._options.alwaysMarkNsfw }}</template>
|
<template #label>{{ i18n.ts._role._options.alwaysMarkNsfw }}</template>
|
||||||
<template #suffix>{{ policies.alwaysMarkNsfw ? i18n.ts.yes : i18n.ts.no }}</template>
|
<template #suffix>{{ policies.alwaysMarkNsfw ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||||
|
|
|
@ -6,15 +6,17 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template>
|
<template>
|
||||||
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
<PageWithHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs">
|
||||||
<MkSpacer :contentMax="800">
|
<MkSpacer :contentMax="800">
|
||||||
<div v-if="tab === 'all'">
|
<MkSwiper v-model:tab="tab" :tabs="headerTabs">
|
||||||
<XNotifications :class="$style.notifications" :excludeTypes="excludeTypes"/>
|
<div v-if="tab === 'all'">
|
||||||
</div>
|
<XNotifications :class="$style.notifications" :excludeTypes="excludeTypes"/>
|
||||||
<div v-else-if="tab === 'mentions'">
|
</div>
|
||||||
<MkNotes :pagination="mentionsPagination"/>
|
<div v-else-if="tab === 'mentions'">
|
||||||
</div>
|
<MkNotes :pagination="mentionsPagination"/>
|
||||||
<div v-else-if="tab === 'directNotes'">
|
</div>
|
||||||
<MkNotes :pagination="directNotesPagination"/>
|
<div v-else-if="tab === 'directNotes'">
|
||||||
</div>
|
<MkNotes :pagination="directNotesPagination"/>
|
||||||
|
</div>
|
||||||
|
</MkSwiper>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</PageWithHeader>
|
</PageWithHeader>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -40,7 +40,7 @@ export function uploadFile(
|
||||||
|
|
||||||
const _folder = typeof folder === 'string' ? folder : folder?.id;
|
const _folder = typeof folder === 'string' ? folder : folder?.id;
|
||||||
|
|
||||||
if (file.size > instance.maxFileSize) {
|
if ((file.size > instance.maxFileSize) || (file.size > ($i.policies.maxFileSizeMb * 1024 * 1024))) {
|
||||||
alert({
|
alert({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: i18n.ts.failedToUpload,
|
title: i18n.ts.failedToUpload,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"name": "misskey-js",
|
"name": "misskey-js",
|
||||||
"version": "2025.4.1-alpha.2",
|
"version": "2025.4.1-beta.0",
|
||||||
"description": "Misskey SDK for JavaScript",
|
"description": "Misskey SDK for JavaScript",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
|
|
|
@ -5216,6 +5216,7 @@ export type components = {
|
||||||
canUseTranslator: boolean;
|
canUseTranslator: boolean;
|
||||||
canHideAds: boolean;
|
canHideAds: boolean;
|
||||||
driveCapacityMb: number;
|
driveCapacityMb: number;
|
||||||
|
maxFileSizeMb: number;
|
||||||
alwaysMarkNsfw: boolean;
|
alwaysMarkNsfw: boolean;
|
||||||
canUpdateBioMedia: boolean;
|
canUpdateBioMedia: boolean;
|
||||||
pinLimit: number;
|
pinLimit: number;
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
'packages/misskey-reversi/**/package.json',
|
'packages/misskey-reversi/**/package.json',
|
||||||
'packages/sw/**/package.json',
|
'packages/sw/**/package.json',
|
||||||
],
|
],
|
||||||
|
// prevent wastage of Chromatic snapshots
|
||||||
|
rebaseWhen: 'never',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
groupName: '[misskey-js] Update dependencies',
|
groupName: '[misskey-js] Update dependencies',
|
||||||
|
|
Loading…
Reference in New Issue