summaryrefslogtreecommitdiff
path: root/packages/frontend/src/ui/deck/tl-note-notification.ts
blob: 728c0d0d298e5b24b29f9dc1eace70e2e0c0b3af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
 * SPDX-FileCopyrightText: syuilo and misskey-project
 * SPDX-License-Identifier: AGPL-3.0-only
 */

import * as Misskey from 'misskey-js';
import type { Ref } from 'vue';
import type { SoundType } from '@/utility/sound.js';
import type { SoundStore } from '@/preferences/def.js';
import { getSoundDuration, playMisskeySfxFile, soundsTypes } from '@/utility/sound.js';
import { i18n } from '@/i18n.js';
import * as os from '@/os.js';

export async function soundSettingsButton(soundSetting: Ref<SoundStore>): Promise<void> {
	function getSoundTypeName(f: SoundType): string {
		switch (f) {
			case null:
				return i18n.ts.none;
			case '_driveFile_':
				return i18n.ts._soundSettings.driveFile;
			default:
				return f;
		}
	}

	const { canceled, result } = await os.form(i18n.ts.sound, {
		type: {
			type: 'enum',
			label: i18n.ts.sound,
			default: soundSetting.value.type ?? 'none',
			enum: soundsTypes.map(f => ({
				value: f ?? 'none', label: getSoundTypeName(f),
			})),
		},
		soundFile: {
			type: 'drive-file',
			label: i18n.ts.file,
			defaultFileId: soundSetting.value.type === '_driveFile_' ? soundSetting.value.fileId : null,
			hidden: v => v.type !== '_driveFile_',
			validate: async (file: Misskey.entities.DriveFile) => {
				if (!file.type.startsWith('audio')) {
					os.alert({
						type: 'warning',
						title: i18n.ts._soundSettings.driveFileTypeWarn,
						text: i18n.ts._soundSettings.driveFileTypeWarnDescription,
					});
					return false;
				}

				const duration = await getSoundDuration(file.url);
				if (duration >= 2000) {
					const { canceled } = await os.confirm({
						type: 'warning',
						title: i18n.ts._soundSettings.driveFileDurationWarn,
						text: i18n.ts._soundSettings.driveFileDurationWarnDescription,
						okText: i18n.ts.continue,
						cancelText: i18n.ts.cancel,
					});
					if (canceled) return false;
				}

				return true;
			},
		},
		volume: {
			type: 'range',
			label: i18n.ts.volume,
			default: soundSetting.value.volume ?? 1,
			textConverter: (v) => `${Math.floor(v * 100)}%`,
			min: 0,
			max: 1,
			step: 0.05,
		},
		listen: {
			type: 'button',
			content: i18n.ts.listen,
			action: (_, v) => {
				const sound = buildSoundStore(v);
				if (!sound) return;
				playMisskeySfxFile(sound);
			},
		},
	});
	if (canceled) return;

	const res = buildSoundStore(result);
	if (res) soundSetting.value = res;

	function buildSoundStore(result: any): SoundStore | null {
		const type = (result.type === 'none' ? null : result.type) as SoundType;
		const volume = result.volume as number;
		const fileId = result.soundFile?.id ?? (soundSetting.value.type === '_driveFile_' ? soundSetting.value.fileId : undefined);
		const fileUrl = result.soundFile?.url ?? (soundSetting.value.type === '_driveFile_' ? soundSetting.value.fileUrl : undefined);

		if (type === '_driveFile_') {
			if (!fileUrl || !fileId) {
				os.alert({
					type: 'warning',
					text: i18n.ts._soundSettings.driveFileWarn,
				});
				return null;
			}
			return { type, volume, fileId, fileUrl };
		} else {
			return { type, volume };
		}
	}
}