summaryrefslogtreecommitdiff
path: root/packages/frontend/src/widgets
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2026-01-09 22:06:40 +0900
committerGitHub <noreply@github.com>2026-01-09 22:06:40 +0900
commit41592eafb363e3c62ab2d3e5f41b38d7d083d3fb (patch)
tree8f69243a5482ad4161eb28b69769684a221aa05c /packages/frontend/src/widgets
parentfix(frontend): popupのemit型が正しく利用できるように修正 (#16... (diff)
downloadmisskey-41592eafb363e3c62ab2d3e5f41b38d7d083d3fb.tar.gz
misskey-41592eafb363e3c62ab2d3e5f41b38d7d083d3fb.tar.bz2
misskey-41592eafb363e3c62ab2d3e5f41b38d7d083d3fb.zip
refactor: make noImplicitAny true (#17083)
* wip * Update emojis.emoji.vue * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update manager.ts * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update analytics.ts
Diffstat (limited to 'packages/frontend/src/widgets')
-rw-r--r--packages/frontend/src/widgets/WidgetActivity.chart.vue25
-rw-r--r--packages/frontend/src/widgets/WidgetFederation.vue8
-rw-r--r--packages/frontend/src/widgets/WidgetInstanceCloud.vue4
-rw-r--r--packages/frontend/src/widgets/WidgetJobQueue.vue23
-rw-r--r--packages/frontend/src/widgets/WidgetMemo.vue4
-rw-r--r--packages/frontend/src/widgets/WidgetPhotos.vue4
-rw-r--r--packages/frontend/src/widgets/WidgetTimeline.vue6
-rw-r--r--packages/frontend/src/widgets/index.ts4
-rw-r--r--packages/frontend/src/widgets/widget.ts11
9 files changed, 51 insertions, 38 deletions
diff --git a/packages/frontend/src/widgets/WidgetActivity.chart.vue b/packages/frontend/src/widgets/WidgetActivity.chart.vue
index e708343b3a..bab688f851 100644
--- a/packages/frontend/src/widgets/WidgetActivity.chart.vue
+++ b/packages/frontend/src/widgets/WidgetActivity.chart.vue
@@ -53,19 +53,27 @@ const pointsReply = ref<string>();
const pointsRenote = ref<string>();
const pointsTotal = ref<string>();
-function dragListen(fn) {
+function dragListen(fn: (ev: MouseEvent | TouchEvent) => void) {
window.addEventListener('mousemove', fn);
window.addEventListener('mouseleave', dragClear.bind(null, fn));
window.addEventListener('mouseup', dragClear.bind(null, fn));
}
-function dragClear(fn) {
+function dragClear(fn: (ev: MouseEvent | TouchEvent) => void) {
window.removeEventListener('mousemove', fn);
- window.removeEventListener('mouseleave', dragClear);
- window.removeEventListener('mouseup', dragClear);
+ window.removeEventListener('mouseleave', dragClear as any);
+ window.removeEventListener('mouseup', dragClear as any);
}
-function onMousedown(ev) {
+function getPositionX(event: MouseEvent | TouchEvent) {
+ return 'touches' in event && event.touches.length > 0 ? event.touches[0].clientX : 'clientX' in event ? event.clientX : 0;
+}
+
+function getPositionY(event: MouseEvent | TouchEvent) {
+ return 'touches' in event && event.touches.length > 0 ? event.touches[0].clientY : 'clientY' in event ? event.clientY : 0;
+}
+
+function onMousedown(ev: MouseEvent) {
const clickX = ev.clientX;
const clickY = ev.clientY;
const baseZoom = zoom.value;
@@ -73,8 +81,11 @@ function onMousedown(ev) {
// 動かした時
dragListen(me => {
- let moveLeft = me.clientX - clickX;
- let moveTop = me.clientY - clickY;
+ const x = getPositionX(me);
+ const y = getPositionY(me);
+
+ let moveLeft = x - clickX;
+ let moveTop = y - clickY;
zoom.value = Math.max(1, baseZoom + (-moveTop / 20));
pos.value = Math.min(0, basePos + moveLeft);
diff --git a/packages/frontend/src/widgets/WidgetFederation.vue b/packages/frontend/src/widgets/WidgetFederation.vue
index 91a3e61201..cf2c2f0ab7 100644
--- a/packages/frontend/src/widgets/WidgetFederation.vue
+++ b/packages/frontend/src/widgets/WidgetFederation.vue
@@ -63,7 +63,7 @@ const instances = ref<Misskey.entities.FederationInstance[]>([]);
const charts = ref<Misskey.entities.ChartsInstanceResponse[]>([]);
const fetching = ref(true);
-const fetch = async () => {
+async function fetchInstances() {
const fetchedInstances = await misskeyApi('federation/instances', {
sort: '+latestRequestReceivedAt',
limit: 5,
@@ -72,14 +72,14 @@ const fetch = async () => {
instances.value = fetchedInstances;
charts.value = fetchedCharts;
fetching.value = false;
-};
+}
-useInterval(fetch, 1000 * 60, {
+useInterval(fetchInstances, 1000 * 60, {
immediate: true,
afterMounted: true,
});
-function getInstanceIcon(instance): string {
+function getInstanceIcon(instance: Misskey.entities.FederationInstance): string {
return getProxiedImageUrlNullable(instance.iconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? '/client-assets/dummy.png';
}
diff --git a/packages/frontend/src/widgets/WidgetInstanceCloud.vue b/packages/frontend/src/widgets/WidgetInstanceCloud.vue
index 6a8e30f54a..c1e864bdb3 100644
--- a/packages/frontend/src/widgets/WidgetInstanceCloud.vue
+++ b/packages/frontend/src/widgets/WidgetInstanceCloud.vue
@@ -55,7 +55,7 @@ const { widgetProps, configure } = useWidgetPropsManager(name,
const cloud = useTemplateRef('cloud');
const activeInstances = shallowRef<Misskey.entities.FederationInstance[] | null>(null);
-function onInstanceClick(i) {
+function onInstanceClick(i: Misskey.entities.FederationInstance) {
os.pageWindow(`/instance-info/${i.host}`);
}
@@ -72,7 +72,7 @@ useInterval(() => {
afterMounted: true,
});
-function getInstanceIcon(instance): string {
+function getInstanceIcon(instance: Misskey.entities.FederationInstance): string {
return getProxiedImageUrlNullable(instance.iconUrl, 'preview') ?? getProxiedImageUrlNullable(instance.faviconUrl, 'preview') ?? '/client-assets/dummy.png';
}
diff --git a/packages/frontend/src/widgets/WidgetJobQueue.vue b/packages/frontend/src/widgets/WidgetJobQueue.vue
index 877baaea02..1727ea9b74 100644
--- a/packages/frontend/src/widgets/WidgetJobQueue.vue
+++ b/packages/frontend/src/widgets/WidgetJobQueue.vue
@@ -52,6 +52,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { onUnmounted, reactive, ref } from 'vue';
+import * as Misskey from 'misskey-js';
import { useWidgetPropsManager } from './widget.js';
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
@@ -116,20 +117,22 @@ if (prefer.s['sound.masterVolume']) {
}
for (const domain of ['inbox', 'deliver']) {
- prev[domain] = deepClone(current[domain]);
+ const d = domain as 'inbox' | 'deliver';
+ prev[d] = deepClone(current[d]);
}
-const onStats = (stats) => {
+const onStats = (stats: Misskey.entities.QueueStats) => {
for (const domain of ['inbox', 'deliver']) {
- prev[domain] = deepClone(current[domain]);
- current[domain].activeSincePrevTick = stats[domain].activeSincePrevTick;
- current[domain].active = stats[domain].active;
- current[domain].waiting = stats[domain].waiting;
- current[domain].delayed = stats[domain].delayed;
+ const d = domain as 'inbox' | 'deliver';
+ prev[d] = deepClone(current[d]);
+ current[d].activeSincePrevTick = stats[d].activeSincePrevTick;
+ current[d].active = stats[d].active;
+ current[d].waiting = stats[d].waiting;
+ current[d].delayed = stats[d].delayed;
- if (current[domain].waiting > 0 && widgetProps.sound && jammedAudioBuffer.value && !jammedSoundNodePlaying.value) {
+ if (current[d].waiting > 0 && widgetProps.sound && jammedAudioBuffer.value && !jammedSoundNodePlaying.value) {
const soundNode = sound.createSourceNode(jammedAudioBuffer.value, {}).soundSource;
- if (soundNode) {
+ if (soundNode != null) {
jammedSoundNodePlaying.value = true;
soundNode.onended = () => jammedSoundNodePlaying.value = false;
soundNode.start();
@@ -138,7 +141,7 @@ const onStats = (stats) => {
}
};
-const onStatsLog = (statsLog) => {
+const onStatsLog = (statsLog: Misskey.entities.QueueStatsLog) => {
for (const stats of [...statsLog].reverse()) {
onStats(stats);
}
diff --git a/packages/frontend/src/widgets/WidgetMemo.vue b/packages/frontend/src/widgets/WidgetMemo.vue
index f96a11f059..fd5b56991e 100644
--- a/packages/frontend/src/widgets/WidgetMemo.vue
+++ b/packages/frontend/src/widgets/WidgetMemo.vue
@@ -52,7 +52,7 @@ const { widgetProps, configure } = useWidgetPropsManager(name,
const text = ref<string | null>(store.s.memo);
const changed = ref(false);
-let timeoutId;
+let timeoutId: number | null = null;
const saveMemo = () => {
store.set('memo', text.value);
@@ -61,7 +61,7 @@ const saveMemo = () => {
const onChange = () => {
changed.value = true;
- window.clearTimeout(timeoutId);
+ if (timeoutId != null) window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(saveMemo, 1000);
};
diff --git a/packages/frontend/src/widgets/WidgetPhotos.vue b/packages/frontend/src/widgets/WidgetPhotos.vue
index 4f592911d4..670e764c8c 100644
--- a/packages/frontend/src/widgets/WidgetPhotos.vue
+++ b/packages/frontend/src/widgets/WidgetPhotos.vue
@@ -64,12 +64,12 @@ const connection = useStream().useChannel('main');
const images = ref<Misskey.entities.DriveFile[]>([]);
const fetching = ref(true);
-const onDriveFileCreated = (file) => {
+function onDriveFileCreated(file: Misskey.entities.DriveFile) {
if (/^image\/.+$/.test(file.type)) {
images.value.unshift(file);
if (images.value.length > 9) images.value.pop();
}
-};
+}
const thumbnail = (image: Misskey.entities.DriveFile): string => {
return prefer.s.disableShowingAnimatedImages
diff --git a/packages/frontend/src/widgets/WidgetTimeline.vue b/packages/frontend/src/widgets/WidgetTimeline.vue
index 6c775fd98c..5d65b001e0 100644
--- a/packages/frontend/src/widgets/WidgetTimeline.vue
+++ b/packages/frontend/src/widgets/WidgetTimeline.vue
@@ -41,13 +41,13 @@ import * as Misskey from 'misskey-js';
import { useWidgetPropsManager } from './widget.js';
import type { WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
+import type { MenuItem } from '@/types/menu.js';
import * as os from '@/os.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import MkContainer from '@/components/MkContainer.vue';
import MkStreamingNotesTimeline from '@/components/MkStreamingNotesTimeline.vue';
import { i18n } from '@/i18n.js';
import { availableBasicTimelines, isAvailableBasicTimeline, isBasicTimeline, basicTimelineIconClass, basicTimelineTypes } from '@/timelines.js';
-import type { MenuItem } from '@/types/menu.js';
const name = 'timeline';
@@ -98,7 +98,7 @@ const headerTitle = computed<string>(() => {
} else if (widgetProps.src === 'antenna' && widgetProps.antenna != null) {
return widgetProps.antenna.name;
} else {
- return i18n.ts._timelines[widgetProps.src];
+ return (i18n.ts._timelines as any)[widgetProps.src] ?? '?';
}
});
@@ -107,7 +107,7 @@ const setSrc = (src: TlSrc) => {
save();
};
-const choose = async (ev: MouseEvent) => {
+const choose = async (ev: PointerEvent) => {
menuOpened.value = true;
const [antennas, lists] = await Promise.all([
misskeyApi('antennas/list'),
diff --git a/packages/frontend/src/widgets/index.ts b/packages/frontend/src/widgets/index.ts
index aea810d1ea..b3351be45f 100644
--- a/packages/frontend/src/widgets/index.ts
+++ b/packages/frontend/src/widgets/index.ts
@@ -42,7 +42,7 @@ export default function(app: App) {
export const federationWidgets = [
'federation',
'instanceCloud',
-];
+] as const;
export const widgets = [
'profile',
@@ -74,4 +74,4 @@ export const widgets = [
'chat',
...federationWidgets,
-];
+] as const;
diff --git a/packages/frontend/src/widgets/widget.ts b/packages/frontend/src/widgets/widget.ts
index 603cf8a31d..cab6177247 100644
--- a/packages/frontend/src/widgets/widget.ts
+++ b/packages/frontend/src/widgets/widget.ts
@@ -5,12 +5,11 @@
import { defineAsyncComponent, reactive, watch } from 'vue';
import { throttle } from 'throttle-debounce';
-import { getDefaultFormValues } from '@/utility/form.js';
import type { Reactive } from 'vue';
import type { FormWithDefault, GetFormResultType } from '@/utility/form.js';
+import { getDefaultFormValues } from '@/utility/form.js';
import * as os from '@/os.js';
import { deepClone } from '@/utility/clone.js';
-import { i18n } from '@/i18n';
export type Widget<P extends Record<string, unknown>> = {
id: string;
@@ -22,7 +21,7 @@ export type WidgetComponentProps<P extends Record<string, unknown>> = {
};
export type WidgetComponentEmits<P extends Record<string, unknown>> = {
- (ev: 'updateProps', props: P);
+ (ev: 'updateProps', props: P): void;
};
export type WidgetComponentExpose = {
@@ -54,7 +53,7 @@ export const useWidgetPropsManager = <F extends FormWithDefault>(
watch(() => props.widget?.data, (to) => {
if (to != null) {
for (const key of Object.keys(propsDef)) {
- widgetProps[key] = to[key];
+ (widgetProps as any)[key] = to[key];
}
}
}, { deep: true });
@@ -66,7 +65,7 @@ export const useWidgetPropsManager = <F extends FormWithDefault>(
const configure = async () => {
const form = deepClone(propsDef);
for (const item of Object.keys(form)) {
- form[item].default = widgetProps[item];
+ form[item].default = (widgetProps as any)[item];
}
const res = await new Promise<{
@@ -97,7 +96,7 @@ export const useWidgetPropsManager = <F extends FormWithDefault>(
}
for (const key of Object.keys(res.result)) {
- widgetProps[key] = res.result[key];
+ (widgetProps as any)[key] = res.result[key];
}
save();