Merge branch 'develop' into acct-parse-url
This commit is contained in:
commit
38f6ff4304
|
@ -1668,7 +1668,7 @@ _serverSettings:
|
|||
restartServerSetupWizardConfirm_text: "Algunes configuracions actuals seran restablertes."
|
||||
entrancePageStyle: "Estil de la pàgina d'inici"
|
||||
showTimelineForVisitor: "Mostrar la línia de temps"
|
||||
showActivityiesForVisitor: "Mostrar les activitats"
|
||||
showActivitiesForVisitor: "Mostrar activitat"
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "Tot obert al públic "
|
||||
localOnly: "Només es publiquen els continguts locals, el contingut remot es manté privat"
|
||||
|
@ -3120,6 +3120,7 @@ _serverSetupWizard:
|
|||
youCanConfigureMoreFederationSettingsLater: "Les configuracions avançades, com especificar els servidors amb els quals es pot federar, es poden fer més tard."
|
||||
remoteContentsCleaning: "Neteja automàtica del contingut rebut"
|
||||
remoteContentsCleaning_description: "Quan es comença a federar es rep un munt de contingut, quan s'activa la neteja automàtica el contingut antic que no es consulta serà eliminat del servidor, el que permet estalviar espai d'emmagatzematge."
|
||||
remoteContentsCleaning_description2: "Alguns mètodes de referència, com els enllaços, no poden ser detectats pel sistema."
|
||||
adminInfo: "Informació de l'administrador "
|
||||
adminInfo_description: "Estableix la informació de l'administrador que es farà servir per rebre consultes."
|
||||
adminInfo_mustBeFilled: "Aquesta informació ha de ser omplerta si el servidor té els registres oberts o la federació es troba activada."
|
||||
|
|
|
@ -1218,8 +1218,8 @@ showRepliesToOthersInTimeline: "Show replies to others in timeline"
|
|||
hideRepliesToOthersInTimeline: "Hide replies to others from timeline"
|
||||
showRepliesToOthersInTimelineAll: "Show replies to others from everyone you follow in timeline"
|
||||
hideRepliesToOthersInTimelineAll: "Hide replies to others from everyone you follow in timeline"
|
||||
confirmShowRepliesAll: "This operation is irreversible. Would you really like to show replies to others from everyone you follow in your timeline?"
|
||||
confirmHideRepliesAll: "This operation is irreversible. Would you really like to hide replies to others from everyone you follow in your timeline?"
|
||||
confirmShowRepliesAll: "Are you sure you want to show replies from everyone you follow in your timeline? This action is irreversible."
|
||||
confirmHideRepliesAll: "Are you sure you want to hide replies from everyone you follow in your timeline? This action is irreversible."
|
||||
externalServices: "External Services"
|
||||
sourceCode: "Source code"
|
||||
sourceCodeIsNotYetProvided: "Source code is not yet available. Contact the administrator to fix this problem."
|
||||
|
@ -1668,7 +1668,6 @@ _serverSettings:
|
|||
restartServerSetupWizardConfirm_text: "Some current settings will be reset."
|
||||
entrancePageStyle: "Entrance page style"
|
||||
showTimelineForVisitor: "Show timeline"
|
||||
showActivityiesForVisitor: "Show activities"
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "Everything is public"
|
||||
localOnly: "Only local content is published, remote content is kept private"
|
||||
|
|
|
@ -1668,7 +1668,7 @@ _serverSettings:
|
|||
restartServerSetupWizardConfirm_text: "Algunas configuraciones actuales se restablecerán"
|
||||
entrancePageStyle: "Estilo de la página de inicio"
|
||||
showTimelineForVisitor: "Mostrar la línea de tiempo"
|
||||
showActivityiesForVisitor: "Mostrar actividades"
|
||||
showActivitiesForVisitor: "Mostrar actividades"
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "Todo es público."
|
||||
localOnly: "Sólo se publica el contenido local, el remoto se mantiene privado"
|
||||
|
@ -3120,6 +3120,7 @@ _serverSetupWizard:
|
|||
youCanConfigureMoreFederationSettingsLater: "Los ajustes avanzados, como la especificación de servidores federados, pueden configurarse más adelante."
|
||||
remoteContentsCleaning: "Limpieza automática de los contenidos recibidos"
|
||||
remoteContentsCleaning_description: "La federación puede dar lugar a un flujo continuo de contenido. Al habilitar la limpieza automática, se eliminará del servidor el contenido obsoleto y sin referencias para ahorrar espacio de almacenamiento."
|
||||
remoteContentsCleaning_description2: "Ciertos métodos de referencia, como los hipervínculos, no pueden ser detectados por el sistema."
|
||||
adminInfo: "Información del administrador"
|
||||
adminInfo_description: "Establece la información del administrador para recibir consultas."
|
||||
adminInfo_mustBeFilled: "Esta información debe ser introducida en el caso de registros abiertos o la federación esté activada."
|
||||
|
|
|
@ -1668,7 +1668,7 @@ _serverSettings:
|
|||
restartServerSetupWizardConfirm_text: "Verranno ripristinate alcune tue impostazioni personalizzate."
|
||||
entrancePageStyle: "Stile della pagina di ingresso"
|
||||
showTimelineForVisitor: "Mostra la Timeline a visitatori non autenticati"
|
||||
showActivityiesForVisitor: "Mostra le attività a visitatori non autenticati"
|
||||
showActivitiesForVisitor: "Mostrare la propria attività"
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "Tutto pubblico"
|
||||
localOnly: "Pubblica solo contenuti locali, mantieni privati i contenuti remoti"
|
||||
|
@ -3120,6 +3120,7 @@ _serverSetupWizard:
|
|||
youCanConfigureMoreFederationSettingsLater: "Puoi svolgere la configurazione avanzata anche dopo. Ad esempio specificando quali server possono federarsi."
|
||||
remoteContentsCleaning: "Pulizia automatica dei contenuti in arrivo"
|
||||
remoteContentsCleaning_description: "Con la federazione funzionante, riceverai sempre più contenuti. Abilitando la pulizia automatica, i contenuti non referenziati e obsoleti verranno rimossi automaticamente dai tuoi server, risparmiando spazio di archiviazione."
|
||||
remoteContentsCleaning_description2: "Alcuni metodi di riferimento, come i collegamenti ipertestuali, non possono essere rilevati sul sistema."
|
||||
adminInfo: "Informazioni sull'amministratore"
|
||||
adminInfo_description: "Imposta le informazioni dell'amministratore utilizzate per accettare le richieste."
|
||||
adminInfo_mustBeFilled: "Questa operazione è necessaria su un server aperto o se è attiva la federazione."
|
||||
|
|
|
@ -1668,7 +1668,7 @@ _serverSettings:
|
|||
restartServerSetupWizardConfirm_text: "현재 일부 설정은 리셋됩니다."
|
||||
entrancePageStyle: "입구 페이지의 스타일"
|
||||
showTimelineForVisitor: "타임라인 표시"
|
||||
showActivityiesForVisitor: "활동 표시"
|
||||
showActivitiesForVisitor: "액티비티 표시하기"
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "모두 공개"
|
||||
localOnly: "로컬 콘텐츠만 공개하고 리모트 콘텐츠는 비공개"
|
||||
|
@ -3120,6 +3120,7 @@ _serverSetupWizard:
|
|||
youCanConfigureMoreFederationSettingsLater: "나중에 연합 가능한 서버의 지정 등 고급 설정을 할 수 있습니다."
|
||||
remoteContentsCleaning: "리모트 콘텐츠 자동 정리"
|
||||
remoteContentsCleaning_description: "연합 중인 서버가 있는 경우, 리모트 서버에서 대단히 많은 콘텐츠를 받아오게 됩니다. 자동 정리 기능을 활성화하면, 오래되고 서버에서 더 이상 조회되지 않는 콘텐츠를 자동으로 서버에서 삭제하여, 스토리지를 절약할 수 있습니다."
|
||||
remoteContentsCleaning_description2: "로컬 내 원격 콘텐츠로의 하이퍼링크는 깨진 링크로 됩니다."
|
||||
adminInfo: "관리자 정보"
|
||||
adminInfo_description: "문의 접수를 위해 사용되는 관리자 정보를 설정합니다."
|
||||
adminInfo_mustBeFilled: "오픈 서버 혹은 연합이 켜져 있는 경우 반드시 입력해야 합니다."
|
||||
|
|
|
@ -1668,7 +1668,6 @@ _serverSettings:
|
|||
restartServerSetupWizardConfirm_text: "Bazı mevcut ayarlar sıfırlanacaktır."
|
||||
entrancePageStyle: "Giriş sayfası stili"
|
||||
showTimelineForVisitor: "Panoyu göster"
|
||||
showActivityiesForVisitor: "Aktiviteleri göster"
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "Her şey halka açıktır."
|
||||
localOnly: "Yalnızca yerel içerik yayınlanır, uzak içerik gizli tutulur."
|
||||
|
|
|
@ -1668,7 +1668,7 @@ _serverSettings:
|
|||
restartServerSetupWizardConfirm_text: "现有的部分设定将重置。"
|
||||
entrancePageStyle: "入口页面样式"
|
||||
showTimelineForVisitor: "显示时间线"
|
||||
showActivityiesForVisitor: "显示活动"
|
||||
showActivitiesForVisitor: "显示活动"
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "全部公开"
|
||||
localOnly: "仅公开本地内容,隐藏远程内容"
|
||||
|
@ -3120,6 +3120,7 @@ _serverSetupWizard:
|
|||
youCanConfigureMoreFederationSettingsLater: "可在之后进行如哪些服务器可以进行联合等高级设置。"
|
||||
remoteContentsCleaning: "自动清理传入内容"
|
||||
remoteContentsCleaning_description: "加入联合后,服务器将持续接收大量内容。打开自动清理后,将自动删除无法找到的旧内容,可节省存储空间。"
|
||||
remoteContentsCleaning_description2: "如超链接之类的某些引用方法无法被系统检测到。"
|
||||
adminInfo: "管理员信息"
|
||||
adminInfo_description: "设置用于接受询问的管理员信息。"
|
||||
adminInfo_mustBeFilled: "开放服务器或开启了联合的情况下必须输入。"
|
||||
|
|
|
@ -1668,7 +1668,7 @@ _serverSettings:
|
|||
restartServerSetupWizardConfirm_text: "當前的部分設定將會被重設。"
|
||||
entrancePageStyle: "入口頁面的樣式"
|
||||
showTimelineForVisitor: "顯示時間軸"
|
||||
showActivityiesForVisitor: "顯示活動"
|
||||
showActivitiesForVisitor: "顯示活動"
|
||||
_userGeneratedContentsVisibilityForVisitor:
|
||||
all: "全部公開\n"
|
||||
localOnly: "僅公開本地內容,遠端內容則不公開\n"
|
||||
|
@ -3120,6 +3120,7 @@ _serverSetupWizard:
|
|||
youCanConfigureMoreFederationSettingsLater: "您可以在稍後進行更高級的設定,例如指定可以聯繫的伺服器等。\n"
|
||||
remoteContentsCleaning: "自動清理接收的內容"
|
||||
remoteContentsCleaning_description: "進行聯邦後,會持續接收大量內容。啟用自動清理功能後,系統會自動從伺服器中刪除未被參照的過時內容,以節省儲存空間。"
|
||||
remoteContentsCleaning_description2: "有些引用方式系統上無法檢測到,例如超連結。"
|
||||
adminInfo: "管理員資訊"
|
||||
adminInfo_description: "設定用於接收查詢的管理者資訊。\n"
|
||||
adminInfo_mustBeFilled: "當設置為開放伺服器或啟用聯邦時,必須填寫此資訊。\n"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "misskey",
|
||||
"version": "2025.8.0-beta.4",
|
||||
"version": "2025.8.0-beta.5",
|
||||
"codename": "nasubi",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -244,7 +244,6 @@ export class WebhookTestService {
|
|||
case 'reaction':
|
||||
return;
|
||||
default: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const _exhaustiveAssertion: never = params.type;
|
||||
return;
|
||||
}
|
||||
|
@ -327,7 +326,6 @@ export class WebhookTestService {
|
|||
break;
|
||||
}
|
||||
default: {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const _exhaustiveAssertion: never = params.type;
|
||||
return;
|
||||
}
|
||||
|
@ -412,7 +410,7 @@ export class WebhookTestService {
|
|||
name: user.name,
|
||||
username: user.username,
|
||||
host: user.host,
|
||||
avatarUrl: user.avatarId == null ? null : user.avatarUrl,
|
||||
avatarUrl: (user.avatarId == null ? null : user.avatarUrl) ?? '',
|
||||
avatarBlurhash: user.avatarId == null ? null : user.avatarBlurhash,
|
||||
avatarDecorations: user.avatarDecorations.map(it => ({
|
||||
id: it.id,
|
||||
|
|
|
@ -471,8 +471,8 @@ export class UserEntityService implements OnModuleInit {
|
|||
(profile.followersVisibility === 'followers') && (relation && relation.isFollowing) ? user.followersCount :
|
||||
null;
|
||||
|
||||
const isModerator = isMe && isDetailed ? this.roleService.isModerator(user) : null;
|
||||
const isAdmin = isMe && isDetailed ? this.roleService.isAdministrator(user) : null;
|
||||
const isModerator = isMe && isDetailed ? this.roleService.isModerator(user) : undefined;
|
||||
const isAdmin = isMe && isDetailed ? this.roleService.isAdministrator(user) : undefined;
|
||||
const unreadAnnouncements = isMe && isDetailed ?
|
||||
(await this.announcementService.getUnreadAnnouncements(user)).map((announcement) => ({
|
||||
createdAt: this.idService.parse(announcement.id).date.toISOString(),
|
||||
|
|
|
@ -465,11 +465,11 @@ export const packedMeDetailedOnlySchema = {
|
|||
},
|
||||
isModerator: {
|
||||
type: 'boolean',
|
||||
nullable: true, optional: false,
|
||||
nullable: false, optional: false,
|
||||
},
|
||||
isAdmin: {
|
||||
type: 'boolean',
|
||||
nullable: true, optional: false,
|
||||
nullable: false, optional: false,
|
||||
},
|
||||
injectFeaturedNote: {
|
||||
type: 'boolean',
|
||||
|
|
|
@ -3,14 +3,13 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
/* eslint-disable import/no-default-export */
|
||||
import type { StoryObj } from '@storybook/vue3';
|
||||
import { HttpResponse, http } from 'msw';
|
||||
import { action } from 'storybook/actions';
|
||||
import { channel } from '../../.storybook/fakes.js';
|
||||
import { commonHandlers } from '../../.storybook/mocks.js';
|
||||
import MkChannelList from './MkChannelList.vue';
|
||||
import type { StoryObj } from '@storybook/vue3';
|
||||
import { Paginator } from '@/utility/paginator.js';
|
||||
export const Default = {
|
||||
render(args) {
|
||||
return {
|
||||
|
@ -33,10 +32,7 @@ export const Default = {
|
|||
};
|
||||
},
|
||||
args: {
|
||||
pagination: {
|
||||
endpoint: 'channels/search',
|
||||
limit: 10,
|
||||
},
|
||||
paginator: new Paginator('channels/search', {}),
|
||||
},
|
||||
parameters: {
|
||||
chromatic: {
|
||||
|
|
|
@ -152,11 +152,12 @@ import { getDriveFileMenu } from '@/utility/get-drive-file-menu.js';
|
|||
import { Paginator } from '@/utility/paginator.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
initialFolder?: Misskey.entities.DriveFolder['id'] | null;
|
||||
initialFolder?: Misskey.entities.DriveFolder | Misskey.entities.DriveFolder['id'] | null;
|
||||
type?: string;
|
||||
multiple?: boolean;
|
||||
select?: 'file' | 'folder' | null;
|
||||
}>(), {
|
||||
initialFolder: null,
|
||||
multiple: false,
|
||||
select: null,
|
||||
});
|
||||
|
|
|
@ -34,9 +34,10 @@ import { deviceKind } from '@/utility/device-kind.js';
|
|||
import { prefer } from '@/preferences.js';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
anchorElement?: HTMLElement;
|
||||
anchorElement?: HTMLElement | null;
|
||||
anchor?: { x: string; y: string; };
|
||||
}>(), {
|
||||
anchorElement: null,
|
||||
anchor: () => ({ x: 'right', y: 'center' }),
|
||||
});
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ function subscribe() {
|
|||
// SEE: https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe#Parameters
|
||||
return promiseDialog(registration.value.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: urlBase64ToUint8Array(instance.swPublickey),
|
||||
applicationServerKey: urlBase64ToBase64(instance.swPublickey),
|
||||
})
|
||||
.then(async subscription => {
|
||||
pushSubscription.value = subscription;
|
||||
|
@ -131,22 +131,16 @@ function encode(buffer: ArrayBuffer | null) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert the URL safe base64 string to a Uint8Array
|
||||
* Convert the URL safe base64 string to a base64 string
|
||||
* @param base64String base64 string
|
||||
*/
|
||||
function urlBase64ToUint8Array(base64String: string): Uint8Array {
|
||||
function urlBase64ToBase64(base64String: string): string {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
return base64;
|
||||
}
|
||||
|
||||
if (navigator.serviceWorker == null) {
|
||||
|
|
|
@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkCaptcha v-if="instance.enableMcaptcha" ref="mcaptcha" v-model="mCaptchaResponse" provider="mcaptcha" :sitekey="instance.mcaptchaSiteKey" :instanceUrl="instance.mcaptchaInstanceUrl"/>
|
||||
<MkCaptcha v-if="instance.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" provider="recaptcha" :sitekey="instance.recaptchaSiteKey"/>
|
||||
<MkCaptcha v-if="instance.enableTurnstile" ref="turnstile" v-model="turnstileResponse" provider="turnstile" :sitekey="instance.turnstileSiteKey"/>
|
||||
<MkCaptcha v-if="instance.enableTestcaptcha" ref="testcaptcha" v-model="testcaptchaResponse" provider="testcaptcha"/>
|
||||
<MkCaptcha v-if="instance.enableTestcaptcha" ref="testcaptcha" v-model="testcaptchaResponse" provider="testcaptcha" :sitekey="null"/>
|
||||
</div>
|
||||
|
||||
<MkButton type="submit" :disabled="needCaptcha && captchaFailed" large primary rounded style="margin: 0 auto;" data-cy-signin-page-password-continue>{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
|
||||
|
|
|
@ -59,7 +59,7 @@ import { isSeparatorNeeded, getSeparatorInfo } from '@/utility/timeline-date-sep
|
|||
import { Paginator } from '@/utility/paginator.js';
|
||||
|
||||
const props = defineProps<{
|
||||
excludeTypes?: typeof notificationTypes[number][];
|
||||
excludeTypes?: typeof notificationTypes[number][] | null;
|
||||
}>();
|
||||
|
||||
const rootEl = useTemplateRef('rootEl');
|
||||
|
|
|
@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkLoading/>
|
||||
</div>
|
||||
<div v-else-if="resolved">
|
||||
<slot :result="result"></slot>
|
||||
<slot :result="result as T"></slot>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div :class="$style.error">
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
|
||||
import { expect, userEvent, waitFor, within } from '@storybook/test';
|
||||
import type { StoryObj } from '@storybook/vue3';
|
||||
import MkAd from './MkAd.vue';
|
||||
import type { StoryObj } from '@storybook/vue3';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
const common = {
|
||||
|
@ -68,7 +67,7 @@ const common = {
|
|||
await expect(imgAgain).toBeInTheDocument();
|
||||
},
|
||||
args: {
|
||||
prefer: [],
|
||||
preferForms: [],
|
||||
specify: {
|
||||
id: 'someadid',
|
||||
ratio: 1,
|
||||
|
|
|
@ -84,7 +84,6 @@ const bound = computed(() => props.link
|
|||
: {});
|
||||
|
||||
const url = computed(() => {
|
||||
if (props.user.avatarUrl == null) return null;
|
||||
if (prefer.s.disableShowingAnimatedImages || prefer.s.dataSaver.avatar) return getStaticImageUrl(props.user.avatarUrl);
|
||||
return props.user.avatarUrl;
|
||||
});
|
||||
|
|
|
@ -54,14 +54,10 @@ router.useListener('change', ({ resolved }) => {
|
|||
if (resolved == null || 'redirect' in resolved.route) return;
|
||||
if (resolved.route.path === currentRoutePath && deepEqual(resolved.props, currentPageProps.value)) return;
|
||||
|
||||
function _() {
|
||||
currentPageComponent.value = resolved.route.component;
|
||||
currentPageProps.value = resolved.props;
|
||||
key.value = router.getCurrentFullPath();
|
||||
currentRoutePath = resolved.route.path;
|
||||
}
|
||||
|
||||
_();
|
||||
currentPageComponent.value = resolved.route.component;
|
||||
currentPageProps.value = resolved.props;
|
||||
key.value = router.getCurrentFullPath();
|
||||
currentRoutePath = resolved.route.path;
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ router.useListener('change', ({ resolved }) => {
|
|||
const fullPath = router.getCurrentFullPath();
|
||||
|
||||
if (tabs.value.some(tab => tab.routePath === routePath && deepEqual(resolved.props, tab.props))) {
|
||||
const newTabs = [];
|
||||
const newTabs = [] as typeof tabs.value;
|
||||
for (const tab of tabs.value) {
|
||||
newTabs.push(tab);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ import { $i } from '@/i.js';
|
|||
|
||||
const customEmojiTags = getCustomEmojiTags();
|
||||
const q = ref('');
|
||||
const searchEmojis = ref<Misskey.entities.EmojiSimple[]>(null);
|
||||
const searchEmojis = ref<Misskey.entities.EmojiSimple[] | null>(null);
|
||||
const selectedTags = ref(new Set());
|
||||
|
||||
function search() {
|
||||
|
|
|
@ -78,7 +78,7 @@ const timeline = computed(() => {
|
|||
return paginator.items.value.map(x => ({
|
||||
id: x.id,
|
||||
timestamp: new Date(x.createdAt).getTime(),
|
||||
data: x,
|
||||
data: x as Misskey.entities.ModerationLog,
|
||||
}));
|
||||
});
|
||||
|
||||
|
|
|
@ -68,6 +68,11 @@ function send() {
|
|||
|
||||
function onEndpointChange() {
|
||||
misskeyApi('endpoint', { endpoint: endpoint.value }, withCredential.value ? undefined : null).then(resp => {
|
||||
if (resp == null) {
|
||||
body.value = '{}';
|
||||
return;
|
||||
}
|
||||
|
||||
const endpointBody = {};
|
||||
for (const p of resp.params) {
|
||||
endpointBody[p.name] =
|
||||
|
|
|
@ -110,6 +110,11 @@ async function search() {
|
|||
|
||||
const type = searchType.value.toString().trim();
|
||||
|
||||
if (type !== 'nameAndDescription' && type !== 'nameOnly') {
|
||||
console.error(`Unrecognized search type: ${type}`);
|
||||
return;
|
||||
}
|
||||
|
||||
channelPaginator.value = markRaw(new Paginator('channels/search', {
|
||||
limit: 10,
|
||||
params: {
|
||||
|
|
|
@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
</div>
|
||||
<div v-else>
|
||||
<MkFoldableSection ref="tagsEl" :foldable="true" :expanded="false" class="_margin">
|
||||
<MkFoldableSection :foldable="true" :expanded="false" class="_margin">
|
||||
<template #header><i class="ti ti-hash ti-fw" style="margin-right: 0.5em;"></i>{{ i18n.ts.popularTags }}</template>
|
||||
|
||||
<div>
|
||||
|
@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</div>
|
||||
</MkFoldableSection>
|
||||
|
||||
<MkFoldableSection v-if="tag != null" :key="`${tag}`" class="_margin">
|
||||
<MkFoldableSection v-if="tagUsersPaginator != null" :key="`${tag}`" class="_margin">
|
||||
<template #header><i class="ti ti-hash ti-fw" style="margin-right: 0.5em;"></i>{{ tag }}</template>
|
||||
<MkUserList :paginator="tagUsersPaginator"/>
|
||||
</MkFoldableSection>
|
||||
|
@ -78,22 +78,17 @@ const props = defineProps<{
|
|||
}>();
|
||||
|
||||
const origin = ref('local');
|
||||
const tagsEl = useTemplateRef('tagsEl');
|
||||
const tagsLocal = ref<Misskey.entities.Hashtag[]>([]);
|
||||
const tagsRemote = ref<Misskey.entities.Hashtag[]>([]);
|
||||
|
||||
watch(() => props.tag, () => {
|
||||
if (tagsEl.value) tagsEl.value.toggleContent(props.tag == null);
|
||||
});
|
||||
|
||||
const tagUsersPaginator = markRaw(new Paginator('hashtags/users', {
|
||||
const tagUsersPaginator = props.tag != null ? markRaw(new Paginator('hashtags/users', {
|
||||
limit: 30,
|
||||
params: {
|
||||
tag: props.tag,
|
||||
origin: 'combined',
|
||||
sort: '+follower',
|
||||
},
|
||||
}));
|
||||
})) : null;
|
||||
|
||||
const pinnedUsersPaginator = markRaw(new Paginator('pinned-users', {
|
||||
noPaging: true,
|
||||
|
|
|
@ -196,13 +196,13 @@ async function run() {
|
|||
|
||||
const isLegacy = !flash.value.script.replaceAll(' ', '').startsWith('///@1.0.0');
|
||||
|
||||
const { Interpreter, Parser, values } = isLegacy ? await import('@syuilo/aiscript-0-19-0') : await import('@syuilo/aiscript');
|
||||
const { Interpreter, Parser, values } = isLegacy ? (await import('@syuilo/aiscript-0-19-0') as any) : await import('@syuilo/aiscript');
|
||||
|
||||
const parser = new Parser();
|
||||
|
||||
components.value = [];
|
||||
|
||||
aiscript.value = new Interpreter({
|
||||
const interpreter = new Interpreter({
|
||||
...createAiScriptEnv({
|
||||
storageKey: 'flash:' + flash.value.id,
|
||||
}),
|
||||
|
@ -221,6 +221,8 @@ async function run() {
|
|||
},
|
||||
});
|
||||
|
||||
aiscript.value = interpreter;
|
||||
|
||||
let ast;
|
||||
try {
|
||||
ast = parser.parse(flash.value.script);
|
||||
|
@ -232,8 +234,8 @@ async function run() {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
await aiscript.value.exec(ast);
|
||||
} catch (err) {
|
||||
await interpreter.exec(ast);
|
||||
} catch (err: any) {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
title: 'AiScript Error',
|
||||
|
|
|
@ -55,11 +55,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkPushNotificationAllowButton ref="allowButton"/>
|
||||
<MkSwitch :disabled="!pushRegistrationInServer" :modelValue="sendReadMessage" @update:modelValue="onChangeSendReadMessage">
|
||||
<template #label>{{ i18n.ts.sendPushNotificationReadMessage }}</template>
|
||||
<template #caption>
|
||||
<I18n :src="i18n.ts.sendPushNotificationReadMessageCaption">
|
||||
<template #emptyPushNotificationMessage>{{ i18n.ts._notification.emptyPushNotificationMessage }}</template>
|
||||
</I18n>
|
||||
</template>
|
||||
<template #caption>{{ i18n.ts.sendPushNotificationReadMessageCaption }}</template>
|
||||
</MkSwitch>
|
||||
</div>
|
||||
</FormSection>
|
||||
|
|
|
@ -40,6 +40,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import MkInput from '@/components/MkInput.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
|
@ -61,7 +62,7 @@ const event_reaction = ref(true);
|
|||
const event_mention = ref(true);
|
||||
|
||||
async function create(): Promise<void> {
|
||||
const events: string[] = [];
|
||||
const events = [] as Misskey.entities.UserWebhook['on'];
|
||||
if (event_follow.value) events.push('follow');
|
||||
if (event_followed.value) events.push('followed');
|
||||
if (event_note.value) events.push('note');
|
||||
|
|
|
@ -34,7 +34,7 @@ const props = withDefaults(defineProps<{
|
|||
limit: 50,
|
||||
});
|
||||
|
||||
const chartSrc = ref('per-user-notes');
|
||||
const chartSrc = ref<'per-user-notes' | 'per-user-pv'>('per-user-notes');
|
||||
|
||||
function showMenu(ev: MouseEvent) {
|
||||
os.popupMenu([{
|
||||
|
|
|
@ -469,6 +469,8 @@ export class PreferencesManager {
|
|||
return local;
|
||||
} else if (choice === 'merge') {
|
||||
return mergedValue!;
|
||||
} else { // TSを黙らすため
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ import { i18n } from '@/i18n.js';
|
|||
import { prefer } from '@/preferences.js';
|
||||
import { openAccountMenu as openAccountMenu_ } from '@/accounts.js';
|
||||
import { $i } from '@/i.js';
|
||||
import { getHTMLElementOrNull } from '@/utility/get-dom-node-or-null.js';
|
||||
|
||||
const WINDOW_THRESHOLD = 1400;
|
||||
|
||||
|
@ -72,8 +73,11 @@ const otherNavItemIndicated = computed<boolean>(() => {
|
|||
});
|
||||
|
||||
async function more(ev: MouseEvent) {
|
||||
const target = getHTMLElementOrNull(ev.currentTarget ?? ev.target);
|
||||
if (!target) return;
|
||||
|
||||
const { dispose } = await os.popupAsyncWithDialog(import('@/components/MkLaunchPad.vue').then(x => x.default), {
|
||||
anchorElement: ev.currentTarget ?? ev.target,
|
||||
anchorElement: target,
|
||||
anchor: { x: 'center', y: 'bottom' },
|
||||
}, {
|
||||
closed: () => dispose(),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"type": "module",
|
||||
"name": "misskey-js",
|
||||
"version": "2025.8.0-beta.4",
|
||||
"version": "2025.8.0-beta.5",
|
||||
"description": "Misskey SDK for JavaScript",
|
||||
"license": "MIT",
|
||||
"main": "./built/index.js",
|
||||
|
|
|
@ -4058,8 +4058,8 @@ export type components = {
|
|||
/** Format: id */
|
||||
bannerId: string | null;
|
||||
followedMessage: string | null;
|
||||
isModerator: boolean | null;
|
||||
isAdmin: boolean | null;
|
||||
isModerator: boolean;
|
||||
isAdmin: boolean;
|
||||
injectFeaturedNote: boolean;
|
||||
receiveAnnouncementEmail: boolean;
|
||||
alwaysMarkNsfw: boolean;
|
||||
|
|
|
@ -49,7 +49,7 @@ export type ModerationLog = {
|
|||
id: ID;
|
||||
createdAt: DateString;
|
||||
userId: User['id'];
|
||||
user: UserDetailedNotMe | null;
|
||||
user: UserDetailedNotMe;
|
||||
} & ({
|
||||
type: 'updateServerSettings';
|
||||
info: ModerationLogPayloads['updateServerSettings'];
|
||||
|
|
Loading…
Reference in New Issue