Merge branch 'develop' into move-json5-to-prod-dependencies

This commit is contained in:
Kainoa Kanter 2023-07-16 22:34:49 +00:00
commit 9a0865da9a
128 changed files with 6621 additions and 4681 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "calckey", "name": "calckey",
"version": "14.0.0-dev78", "version": "14.0.0-dev79",
"codename": "aqua", "codename": "aqua",
"repository": { "repository": {
"type": "git", "type": "git",
@ -57,7 +57,7 @@
"gulp-replace": "1.1.4", "gulp-replace": "1.1.4",
"gulp-terser": "2.1.0", "gulp-terser": "2.1.0",
"install-peers": "^1.0.4", "install-peers": "^1.0.4",
"rome": "^12.1.3", "rome": "^v12.1.3-nightly.f65b0d9",
"start-server-and-test": "1.15.2", "start-server-and-test": "1.15.2",
"typescript": "5.1.6" "typescript": "5.1.6"
} }

View File

@ -1,9 +1,15 @@
export class tweakVarcharLength1678426061773 { export class tweakVarcharLength1678426061773 {
name = 'tweakVarcharLength1678426061773' name = "tweakVarcharLength1678426061773";
async up(queryRunner) { async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "smtpUser" TYPE character varying(1024)`, undefined); await queryRunner.query(
await queryRunner.query(`ALTER TABLE "meta" ALTER COLUMN "smtpPass" TYPE character varying(1024)`, undefined); `ALTER TABLE "meta" ALTER COLUMN "smtpUser" TYPE character varying(1024)`,
undefined,
);
await queryRunner.query(
`ALTER TABLE "meta" ALTER COLUMN "smtpPass" TYPE character varying(1024)`,
undefined,
);
} }
async down(queryRunner) {} async down(queryRunner) {}

View File

@ -43,6 +43,7 @@
"universal": "napi universal", "universal": "napi universal",
"version": "napi version", "version": "napi version",
"format": "cargo fmt --all", "format": "cargo fmt --all",
"lint": "cargo clippy --fix",
"cargo:test": "pnpm run cargo:unit && pnpm run cargo:integration", "cargo:test": "pnpm run cargo:unit && pnpm run cargo:integration",
"cargo:unit": "cargo test unit_test && cargo test -F napi unit_test", "cargo:unit": "cargo test unit_test && cargo test -F napi unit_test",
"cargo:integration": "cargo test -F noarray int_test -- --test-threads=1" "cargo:integration": "cargo test -F noarray int_test -- --test-threads=1"

View File

@ -46,7 +46,7 @@ impl Repository<Antenna> for antenna::Model {
src: self.src.try_into()?, src: self.src.try_into()?,
user_list_id: self.user_list_id, user_list_id: self.user_list_id,
user_group_id, user_group_id,
users: self.users.into(), users: self.users,
instances: self.instances.into(), instances: self.instances.into(),
case_sensitive: self.case_sensitive, case_sensitive: self.case_sensitive,
notify: self.notify, notify: self.notify,

View File

@ -58,7 +58,7 @@ impl TryFrom<AntennaSrcEnum> for super::AntennaSrc {
// ---- TODO: could be macro // ---- TODO: could be macro
impl Schema<Self> for super::Antenna {} impl Schema<Self> for super::Antenna {}
pub static VALIDATOR: Lazy<JSONSchema> = Lazy::new(|| super::Antenna::validator()); pub static VALIDATOR: Lazy<JSONSchema> = Lazy::new(super::Antenna::validator);
// ---- // ----
cfg_if! { cfg_if! {

View File

@ -91,7 +91,7 @@ pub enum AppPermission {
impl Schema<Self> for App {} impl Schema<Self> for App {}
pub static VALIDATOR: Lazy<JSONSchema> = Lazy::new(|| App::validator()); pub static VALIDATOR: Lazy<JSONSchema> = Lazy::new(App::validator);
#[cfg(test)] #[cfg(test)]
mod unit_test { mod unit_test {

View File

@ -148,8 +148,8 @@ async fn setup_model(db: &DbConn) {
let user_model = entity::user::Model { let user_model = entity::user::Model {
id: user_id.to_owned(), id: user_id.to_owned(),
created_at: Utc::now().into(), created_at: Utc::now().into(),
username: name.to_lowercase().to_string(), username: name.to_lowercase(),
username_lower: name.to_lowercase().to_string(), username_lower: name.to_lowercase(),
name: Some(name.to_string()), name: Some(name.to_string()),
token: Some(gen_string(16)), token: Some(gen_string(16)),
is_admin: true, is_admin: true,

View File

@ -43,18 +43,16 @@ mod int_test {
keywords: vec![ keywords: vec![
vec!["foo".to_string(), "bar".to_string()], vec!["foo".to_string(), "bar".to_string()],
vec!["foobar".to_string()], vec!["foobar".to_string()],
] ],
.into(),
exclude_keywords: vec![ exclude_keywords: vec![
vec!["abc".to_string()], vec!["abc".to_string()],
vec!["def".to_string(), "ghi".to_string()], vec!["def".to_string(), "ghi".to_string()],
] ],
.into(),
src: schema::AntennaSrc::All, src: schema::AntennaSrc::All,
user_list_id: None, user_list_id: None,
user_group_id: None, user_group_id: None,
users: vec![].into(), users: vec![],
instances: vec![].into(), instances: vec![],
case_sensitive: true, case_sensitive: true,
notify: true, notify: true,
with_replies: false, with_replies: false,

View File

@ -1,5 +1,8 @@
import config from "@/config/index.js"; import config from "@/config/index.js";
import { DB_MAX_NOTE_TEXT_LENGTH, DB_MAX_IMAGE_COMMENT_LENGTH } from "@/misc/hard-limits.js"; import {
DB_MAX_NOTE_TEXT_LENGTH,
DB_MAX_IMAGE_COMMENT_LENGTH,
} from "@/misc/hard-limits.js";
export const MAX_NOTE_TEXT_LENGTH = Math.min( export const MAX_NOTE_TEXT_LENGTH = Math.min(
config.maxNoteLength ?? 3000, config.maxNoteLength ?? 3000,

View File

@ -24,6 +24,7 @@ export async function downloadUrl(url: string, path: string): Promise<void> {
.stream(url, { .stream(url, {
headers: { headers: {
"User-Agent": config.userAgent, "User-Agent": config.userAgent,
Host: new URL(url).hostname,
}, },
timeout: { timeout: {
lookup: timeout, lookup: timeout,

View File

@ -1,4 +1,6 @@
import * as fs from "node:fs"; import * as fs from "node:fs";
import net from "node:net";
import { promises } from "node:dns";
import type Koa from "koa"; import type Koa from "koa";
import sharp from "sharp"; import sharp from "sharp";
import type { IImage } from "@/services/drive/image-processor.js"; import type { IImage } from "@/services/drive/image-processor.js";
@ -19,6 +21,40 @@ export async function proxyMedia(ctx: Koa.Context) {
return; return;
} }
const { hostname } = new URL(url);
let resolvedIps;
try {
resolvedIps = await promises.resolve(hostname);
} catch (error) {
ctx.status = 400;
ctx.body = { message: "Invalid URL" };
return;
}
const isSSRF = resolvedIps.some((ip) => {
if (net.isIPv4(ip)) {
const parts = ip.split(".").map(Number);
return (
parts[0] === 10 ||
(parts[0] === 172 && parts[1] >= 16 && parts[1] < 32) ||
(parts[0] === 192 && parts[1] === 168) ||
parts[0] === 127 ||
parts[0] === 0
);
} else if (net.isIPv6(ip)) {
return (
ip.startsWith("::") || ip.startsWith("fc00:") || ip.startsWith("fe80:")
);
}
return false;
});
if (isSSRF) {
ctx.status = 400;
ctx.body = { message: "Access to this URL is not allowed" };
return;
}
// Create temp file // Create temp file
const [path, cleanup] = await createTemp(); const [path, cleanup] = await createTemp();

View File

@ -0,0 +1,7 @@
{
"extends": ["@eslint-sets/vue3", "@eslint-sets/vue3-ts"],
"plugins": ["file-progress", "prettier"],
"rules": {
"file-progress/activate": 1
}
}

View File

@ -4,11 +4,14 @@
"scripts": { "scripts": {
"watch": "pnpm vite build --watch --mode development", "watch": "pnpm vite build --watch --mode development",
"build": "pnpm vite build", "build": "pnpm vite build",
"lint": "pnpm rome check \"src/**/*.{ts,vue}\"", "lint": "pnpm rome check **/*.ts --apply && pnpm run lint:vue",
"format": "pnpm rome format * --write && pnpm prettier --write '**/*.{scss,vue}'" "lint:vue": "pnpm paralint --ext .vue --fix '**/*.vue' --cache",
"format": "pnpm rome format * --write && pnpm prettier --write '**/*.{scss,vue}' --cache --cache-strategy metadata"
}, },
"devDependencies": { "devDependencies": {
"@discordapp/twemoji": "14.1.2", "@discordapp/twemoji": "14.1.2",
"@eslint-sets/eslint-config-vue3": "^5.6.1",
"@eslint-sets/eslint-config-vue3-ts": "^3.3.0",
"@phosphor-icons/web": "^2.0.3", "@phosphor-icons/web": "^2.0.3",
"@rollup/plugin-alias": "3.1.9", "@rollup/plugin-alias": "3.1.9",
"@rollup/plugin-json": "4.1.0", "@rollup/plugin-json": "4.1.0",
@ -46,6 +49,8 @@
"date-fns": "2.30.0", "date-fns": "2.30.0",
"emojilib": "github:thatonecalculator/emojilib", "emojilib": "github:thatonecalculator/emojilib",
"escape-regexp": "0.0.1", "escape-regexp": "0.0.1",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-file-progress": "^1.3.0",
"eventemitter3": "5.0.1", "eventemitter3": "5.0.1",
"fast-blurhash": "^1.1.2", "fast-blurhash": "^1.1.2",
"focus-trap": "^7.5.2", "focus-trap": "^7.5.2",
@ -57,6 +62,7 @@
"katex": "0.16.8", "katex": "0.16.8",
"matter-js": "0.18.0", "matter-js": "0.18.0",
"mfm-js": "0.23.3", "mfm-js": "0.23.3",
"paralint": "^1.2.1",
"photoswipe": "5.3.8", "photoswipe": "5.3.8",
"prettier": "3.0.0", "prettier": "3.0.0",
"prettier-plugin-vue": "1.1.6", "prettier-plugin-vue": "1.1.6",

View File

@ -80,11 +80,11 @@ const emit = defineEmits<{
(ev: "resolved", reportId: string): void; (ev: "resolved", reportId: string): void;
}>(); }>();
let forward = $ref(props.report.forwarded); const forward = $ref(props.report.forwarded);
function resolve() { function resolve() {
os.apiWithDialog("admin/resolve-abuse-user-report", { os.apiWithDialog("admin/resolve-abuse-user-report", {
forward: forward, forward,
reportId: props.report.id, reportId: props.report.id,
}).then(() => { }).then(() => {
emit("resolved", props.report.id); emit("resolved", props.report.id);

View File

@ -41,7 +41,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import * as Misskey from "calckey-js"; import type * as Misskey from "calckey-js";
import XWindow from "@/components/MkWindow.vue"; import XWindow from "@/components/MkWindow.vue";
import MkTextarea from "@/components/form/textarea.vue"; import MkTextarea from "@/components/form/textarea.vue";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";

View File

@ -109,12 +109,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import { import {
ref,
computed, computed,
onMounted,
onBeforeUnmount,
shallowRef,
nextTick, nextTick,
onBeforeUnmount,
onMounted,
ref,
shallowRef,
} from "vue"; } from "vue";
import tinycolor from "tinycolor2"; import tinycolor from "tinycolor2";
import { globalEvents } from "@/events.js"; import { globalEvents } from "@/events.js";
@ -173,21 +173,21 @@ const texts = computed(() => {
return angles; return angles;
}); });
let enabled = true; let enabled = true,
let majorGraduationColor = $ref<string>(); majorGraduationColor = $ref<string>(),
// let minorGraduationColor = $ref<string>(); // let minorGraduationColor = $ref<string>();
let sHandColor = $ref<string>(); sHandColor = $ref<string>(),
let mHandColor = $ref<string>(); mHandColor = $ref<string>(),
let hHandColor = $ref<string>(); hHandColor = $ref<string>(),
let nowColor = $ref<string>(); nowColor = $ref<string>(),
let h = $ref<number>(0); h = $ref<number>(0),
let m = $ref<number>(0); m = $ref<number>(0),
let s = $ref<number>(0); s = $ref<number>(0),
let hAngle = $ref<number>(0); hAngle = $ref<number>(0),
let mAngle = $ref<number>(0); mAngle = $ref<number>(0),
let sAngle = $ref<number>(0); sAngle = $ref<number>(0),
let disableSAnimate = $ref(false); disableSAnimate = $ref(false),
let sOneRound = false; sOneRound = false;
function tick() { function tick() {
const now = new Date(); const now = new Date();

View File

@ -85,11 +85,11 @@
<script lang="ts"> <script lang="ts">
import { import {
markRaw, markRaw,
ref,
onUpdated,
onMounted,
onBeforeUnmount,
nextTick, nextTick,
onBeforeUnmount,
onMounted,
onUpdated,
ref,
watch, watch,
} from "vue"; } from "vue";
import contains from "@/scripts/contains"; import contains from "@/scripts/contains";
@ -99,17 +99,17 @@ import { acct } from "@/filters/user";
import * as os from "@/os"; import * as os from "@/os";
import { MFM_TAGS } from "@/scripts/mfm-tags"; import { MFM_TAGS } from "@/scripts/mfm-tags";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";
import { emojilist, addSkinTone } from "@/scripts/emojilist"; import { addSkinTone, emojilist } from "@/scripts/emojilist";
import { instance } from "@/instance"; import { instance } from "@/instance";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
type EmojiDef = { interface EmojiDef {
emoji: string; emoji: string;
name: string; name: string;
aliasOf?: string; aliasOf?: string;
url?: string; url?: string;
isCustomEmoji?: boolean; isCustomEmoji?: boolean;
}; }
const lib = emojilist.filter((x) => x.category !== "flags"); const lib = emojilist.filter((x) => x.category !== "flags");

View File

@ -49,8 +49,8 @@ const emit = defineEmits<{
(ev: "click", payload: MouseEvent): void; (ev: "click", payload: MouseEvent): void;
}>(); }>();
let el = $ref<HTMLElement | null>(null); const el = $ref<HTMLElement | null>(null);
let ripples = $ref<HTMLElement | null>(null); const ripples = $ref<HTMLElement | null>(null);
onMounted(() => { onMounted(() => {
if (props.autofocus) { if (props.autofocus) {

View File

@ -6,11 +6,11 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, onMounted, onBeforeUnmount, watch } from "vue"; import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
type Captcha = { interface Captcha {
render( render(
container: string | Node, container: string | Node,
options: { options: {
@ -31,7 +31,7 @@ type Captcha = {
execute(id: string): void; execute(id: string): void;
reset(id?: string): void; reset(id?: string): void;
getResponse(id: string): string; getResponse(id: string): string;
}; }
type CaptchaProvider = "hcaptcha" | "recaptcha"; type CaptchaProvider = "hcaptcha" | "recaptcha";
@ -105,7 +105,7 @@ function requestRender() {
captcha.value.render(captchaEl.value, { captcha.value.render(captchaEl.value, {
sitekey: props.sitekey, sitekey: props.sitekey,
theme: defaultStore.state.darkMode ? "dark" : "light", theme: defaultStore.state.darkMode ? "dark" : "light",
callback: callback, callback,
"expired-callback": callback, "expired-callback": callback,
"error-callback": callback, "error-callback": callback,
}); });

View File

@ -24,7 +24,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import MkChannelPreview from "@/components/MkChannelPreview.vue"; import MkChannelPreview from "@/components/MkChannelPreview.vue";
import MkPagination, { Paging } from "@/components/MkPagination.vue"; import type { Paging } from "@/components/MkPagination.vue";
import MkPagination from "@/components/MkPagination.vue";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
const props = withDefaults( const props = withDefaults(

View File

@ -8,23 +8,24 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, ref, watch, PropType, onUnmounted } from "vue"; import type { PropType } from "vue";
import { onMounted, onUnmounted, ref, watch } from "vue";
import { import {
Chart,
ArcElement, ArcElement,
LineElement,
BarElement,
PointElement,
BarController, BarController,
LineController, BarElement,
CategoryScale, CategoryScale,
LinearScale, Chart,
TimeScale, Filler,
Legend, Legend,
LineController,
LineElement,
LinearScale,
PointElement,
SubTitle,
TimeScale,
Title, Title,
Tooltip, Tooltip,
SubTitle,
Filler,
} from "chart.js"; } from "chart.js";
import "chartjs-adapter-date-fns"; import "chartjs-adapter-date-fns";
import { enUS } from "date-fns/locale"; import { enUS } from "date-fns/locale";
@ -127,8 +128,8 @@ const getColor = (i) => {
}; };
const now = new Date(); const now = new Date();
let chartInstance: Chart = null; let chartInstance: Chart = null,
let chartData: { chartData: {
series: { series: {
name: string; name: string;
type: "line" | "area"; type: "line" | "area";

View File

@ -26,7 +26,7 @@
: message.user : message.user
" "
:show-indicator="true" :show-indicator="true"
disableLink disable-link
/> />
<header v-if="message.groupId"> <header v-if="message.groupId">
<span class="name">{{ message.group.name }}</span> <span class="name">{{ message.group.name }}</span>

View File

@ -12,9 +12,9 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onBeforeUnmount } from "vue"; import { onBeforeUnmount, onMounted } from "vue";
import MkMenu from "./MkMenu.vue"; import MkMenu from "./MkMenu.vue";
import { MenuItem } from "./types/menu.vue"; import type { MenuItem } from "./types/menu.vue";
import contains from "@/scripts/contains"; import contains from "@/scripts/contains";
import * as os from "@/os"; import * as os from "@/os";
@ -27,13 +27,13 @@ const emit = defineEmits<{
(ev: "closed"): void; (ev: "closed"): void;
}>(); }>();
let rootEl = $ref<HTMLDivElement>(); const rootEl = $ref<HTMLDivElement>();
let zIndex = $ref<number>(os.claimZIndex("high")); const zIndex = $ref<number>(os.claimZIndex("high"));
onMounted(() => { onMounted(() => {
let left = props.ev.pageX + 1; // + 1 let left = props.ev.pageX + 1, // + 1
let top = props.ev.pageY + 1; // + 1 top = props.ev.pageY + 1; // + 1
const width = rootEl.offsetWidth; const width = rootEl.offsetWidth;
const height = rootEl.offsetHeight; const height = rootEl.offsetHeight;

View File

@ -37,7 +37,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { nextTick, onMounted } from "vue"; import { nextTick, onMounted } from "vue";
import * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
import Cropper from "cropperjs"; import Cropper from "cropperjs";
import tinycolor from "tinycolor2"; import tinycolor from "tinycolor2";
import XModalWindow from "@/components/MkModalWindow.vue"; import XModalWindow from "@/components/MkModalWindow.vue";
@ -62,10 +62,10 @@ const props = defineProps<{
const imgUrl = `${url}/proxy/image.webp?${query({ const imgUrl = `${url}/proxy/image.webp?${query({
url: props.file.url, url: props.file.url,
})}`; })}`;
let dialogEl = $ref<InstanceType<typeof XModalWindow>>(); const dialogEl = $ref<InstanceType<typeof XModalWindow>>();
let imgEl = $ref<HTMLImageElement>(); const imgEl = $ref<HTMLImageElement>();
let cropper: Cropper | null = null; let cropper: Cropper | null = null,
let loading = $ref(true); loading = $ref(true);
const ok = async () => { const ok = async () => {
const promise = new Promise<misskey.entities.DriveFile>(async (res) => { const promise = new Promise<misskey.entities.DriveFile>(async (res) => {

View File

@ -15,7 +15,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import { length } from "stringz"; import { length } from "stringz";
import * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
import { concat } from "@/scripts/array"; import { concat } from "@/scripts/array";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";

View File

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, h, PropType, TransitionGroup } from "vue"; import type { PropType } from "vue";
import { TransitionGroup, defineComponent, h } from "vue";
import MkAd from "@/components/global/MkAd.vue"; import MkAd from "@/components/global/MkAd.vue";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";
@ -51,7 +52,7 @@ export default defineComponent({
if (!slots || !slots.default) return; if (!slots || !slots.default) return;
const el = slots.default({ const el = slots.default({
item: item, item,
})[0]; })[0];
if (el.key == null && item.id) el.key = item.id; if (el.key == null && item.id) el.key = item.id;

View File

@ -57,17 +57,17 @@
<Mfm :text="text" /> <Mfm :text="text" />
</div> </div>
<MkInput <MkInput
ref="inputEl"
v-if="input && input.type !== 'paragraph'" v-if="input && input.type !== 'paragraph'"
ref="inputEl"
v-model="inputValue" v-model="inputValue"
autofocus autofocus
:autocomplete="input.autocomplete" :autocomplete="input.autocomplete"
:type="input.type == 'search' ? 'search' : input.type || 'text'" :type="input.type == 'search' ? 'search' : input.type || 'text'"
:placeholder="input.placeholder || undefined" :placeholder="input.placeholder || undefined"
@keydown="onInputKeydown"
:style="{ :style="{
width: input.type === 'search' ? '300px' : null, width: input.type === 'search' ? '300px' : null,
}" }"
@keydown="onInputKeydown"
> >
<template v-if="input.type === 'password'" #prefix <template v-if="input.type === 'password'" #prefix
><i class="ph-password ph-bold ph-lg"></i ><i class="ph-password ph-bold ph-lg"></i
@ -100,9 +100,9 @@
</template> </template>
<template v-if="input.type === 'search'" #suffix> <template v-if="input.type === 'search'" #suffix>
<button <button
v-tooltip.noDelay="i18n.ts.filter"
class="_buttonIcon" class="_buttonIcon"
@click.stop="openSearchFilters" @click.stop="openSearchFilters"
v-tooltip.noDelay="i18n.ts.filter"
> >
<i class="ph-funnel ph-bold"></i> <i class="ph-funnel ph-bold"></i>
</button> </button>
@ -200,6 +200,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onBeforeUnmount, onMounted, ref, shallowRef } from "vue"; import { onBeforeUnmount, onMounted, ref, shallowRef } from "vue";
import * as Acct from "calckey-js/built/acct";
import MkModal from "@/components/MkModal.vue"; import MkModal from "@/components/MkModal.vue";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";
import MkInput from "@/components/form/input.vue"; import MkInput from "@/components/form/input.vue";
@ -207,18 +208,17 @@ import MkTextarea from "@/components/form/textarea.vue";
import MkSelect from "@/components/form/select.vue"; import MkSelect from "@/components/form/select.vue";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import * as Acct from "calckey-js/built/acct";
type Input = { interface Input {
type: HTMLInputElement["type"]; type: HTMLInputElement["type"];
placeholder?: string | null; placeholder?: string | null;
autocomplete?: string; autocomplete?: string;
default: string | number | null; default: string | number | null;
minLength?: number; minLength?: number;
maxLength?: number; maxLength?: number;
}; }
type Select = { interface Select {
items: { items: {
value: string; value: string;
text: string; text: string;
@ -231,7 +231,7 @@ type Select = {
}[]; }[];
}[]; }[];
default: string | null; default: string | null;
}; }
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{

View File

@ -49,8 +49,8 @@
<button <button
class="_button" class="_button"
:class="$style.close" :class="$style.close"
@click="close"
:aria-label="i18n.t('close')" :aria-label="i18n.t('close')"
@click="close"
> >
<i class="ph-x ph-bold ph-lg"></i> <i class="ph-x ph-bold ph-lg"></i>
</button> </button>
@ -59,14 +59,14 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, nextTick } from "vue"; import { nextTick, ref } from "vue";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";
import { host } from "@/config"; import { host } from "@/config";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import * as os from "@/os"; import * as os from "@/os";
import { instance } from "@/instance"; import { instance } from "@/instance";
let show = ref(false); const show = ref(false);
const emit = defineEmits<{ const emit = defineEmits<{
(ev: "closed"): void; (ev: "closed"): void;

View File

@ -195,7 +195,7 @@ const props = withDefaults(
); );
const emit = defineEmits<{ const emit = defineEmits<{
(ev: "chosen", v: string): void; (ev: "chosen", v: string, ev: MouseEvent): void;
}>(); }>();
const search = ref<HTMLInputElement>(); const search = ref<HTMLInputElement>();
@ -436,7 +436,7 @@ function chosen(emoji: any, ev?: MouseEvent) {
} }
const key = getKey(emoji); const key = getKey(emoji);
emit("chosen", key); emit("chosen", key, ev);
// 使 // 使
if (!pinned.value.includes(key)) { if (!pinned.value.includes(key)) {

View File

@ -58,29 +58,15 @@ const emit = defineEmits<{
const modal = ref<InstanceType<typeof MkModal>>(); const modal = ref<InstanceType<typeof MkModal>>();
const picker = ref<InstanceType<typeof MkEmojiPicker>>(); const picker = ref<InstanceType<typeof MkEmojiPicker>>();
const isShiftKeyPressed = ref(false);
const keydownHandler = (e) => {
if (e.key === "Shift") {
isShiftKeyPressed.value = true;
}
};
const keyupHandler = (e) => {
if (e.key === "Shift") {
isShiftKeyPressed.value = false;
}
};
function checkForShift(ev?: MouseEvent) { function checkForShift(ev?: MouseEvent) {
if (!isShiftKeyPressed.value) { if (ev?.shiftKey) return;
modal.value?.close(ev); modal.value?.close(ev);
} }
}
function chosen(emoji: any) { function chosen(emoji: any, ev: MouseEvent) {
emit("done", emoji); emit("done", emoji);
checkForShift(); checkForShift(ev);
} }
function opening() { function opening() {
@ -91,16 +77,6 @@ function opening() {
} }
picker.value?.focus(); picker.value?.focus();
} }
onMounted(() => {
window.addEventListener("keydown", keydownHandler);
window.addEventListener("keyup", keyupHandler);
});
onBeforeUnmount(() => {
window.removeEventListener("keydown", keydownHandler);
window.removeEventListener("keyup", keyupHandler);
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -54,7 +54,7 @@
controls controls
@contextmenu.stop @contextmenu.stop
> >
<source :src="media.url" :type="media.type" /> <source :src="media.url" :type="mediaType" />
</video> </video>
</VuePlyr> </VuePlyr>
</template> </template>
@ -80,7 +80,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { watch, ref } from "vue"; import { watch, ref, computed } from "vue";
import VuePlyr from "vue-plyr"; import VuePlyr from "vue-plyr";
import "vue-plyr/dist/vue-plyr.css"; import "vue-plyr/dist/vue-plyr.css";
import type * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
@ -107,6 +107,12 @@ const url =
? getStaticImageUrl(props.media.thumbnailUrl) ? getStaticImageUrl(props.media.thumbnailUrl)
: props.media.thumbnailUrl; : props.media.thumbnailUrl;
const mediaType = computed(() => {
return props.media.type === "video/quicktime"
? "video/mp4"
: props.media.type;
});
function captionPopup() { function captionPopup() {
os.alert({ os.alert({
type: "info", type: "info",

View File

@ -148,7 +148,7 @@
{{ appearNote.channel.name }}</MkA {{ appearNote.channel.name }}</MkA
> >
</div> </div>
<footer ref="footerEl" class="footer" @click.stop tabindex="-1"> <footer ref="footerEl" class="footer" tabindex="-1">
<XReactionsViewer <XReactionsViewer
v-if="enableEmojiReactions" v-if="enableEmojiReactions"
ref="reactionsViewer" ref="reactionsViewer"
@ -157,7 +157,7 @@
<button <button
v-tooltip.noDelay.bottom="i18n.ts.reply" v-tooltip.noDelay.bottom="i18n.ts.reply"
class="button _button" class="button _button"
@click="reply()" @click.stop="reply()"
> >
<i class="ph-arrow-u-up-left ph-bold ph-lg"></i> <i class="ph-arrow-u-up-left ph-bold ph-lg"></i>
<template <template
@ -202,7 +202,7 @@
ref="reactButton" ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction" v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button" class="button _button"
@click="react()" @click.stop="react()"
> >
<i class="ph-smiley ph-bold ph-lg"></i> <i class="ph-smiley ph-bold ph-lg"></i>
</button> </button>
@ -213,7 +213,7 @@
" "
ref="reactButton" ref="reactButton"
class="button _button reacted" class="button _button reacted"
@click="undoReact(appearNote)" @click.stop="undoReact(appearNote)"
v-tooltip.noDelay.bottom="i18n.ts.removeReaction" v-tooltip.noDelay.bottom="i18n.ts.removeReaction"
> >
<i class="ph-minus ph-bold ph-lg"></i> <i class="ph-minus ph-bold ph-lg"></i>
@ -223,7 +223,7 @@
ref="menuButton" ref="menuButton"
v-tooltip.noDelay.bottom="i18n.ts.more" v-tooltip.noDelay.bottom="i18n.ts.more"
class="button _button" class="button _button"
@click="menu()" @click.stop="menu()"
> >
<i class="ph-dots-three-outline ph-bold ph-lg"></i> <i class="ph-dots-three-outline ph-bold ph-lg"></i>
</button> </button>
@ -862,7 +862,6 @@ defineExpose({
z-index: 2; z-index: 2;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
pointer-events: none; // Allow clicking anything w/out pointer-events: all; to open post
margin-top: 0.4em; margin-top: 0.4em;
> :deep(.button) { > :deep(.button) {
position: relative; position: relative;
@ -876,7 +875,6 @@ defineExpose({
max-width: 3.5em; max-width: 3.5em;
width: max-content; width: max-content;
min-width: max-content; min-width: max-content;
pointer-events: all;
height: auto; height: auto;
transition: opacity 0.2s; transition: opacity 0.2s;
&::before { &::before {

View File

@ -33,11 +33,7 @@
detailedView detailedView
></MkNote> ></MkNote>
<MkTab <MkTab v-model="tab" :style="'underline'" @update:modelValue="loadTab">
v-model="tab"
:style="'underline'"
@update:modelValue="loadTab"
>
<option value="replies"> <option value="replies">
<!-- <i class="ph-arrow-u-up-left ph-bold ph-lg"></i> --> <!-- <i class="ph-arrow-u-up-left ph-bold ph-lg"></i> -->
<span v-if="note.repliesCount > 0" class="count">{{ <span v-if="note.repliesCount > 0" class="count">{{

View File

@ -56,7 +56,7 @@
</div> </div>
</div> </div>
</div> </div>
<footer ref="footerEl" class="footer" @click.stop tabindex="-1"> <footer ref="footerEl" class="footer" tabindex="-1">
<XReactionsViewer <XReactionsViewer
v-if="enableEmojiReactions" v-if="enableEmojiReactions"
ref="reactionsViewer" ref="reactionsViewer"
@ -65,7 +65,7 @@
<button <button
v-tooltip.noDelay.bottom="i18n.ts.reply" v-tooltip.noDelay.bottom="i18n.ts.reply"
class="button _button" class="button _button"
@click="reply()" @click.stop="reply()"
> >
<i class="ph-arrow-u-up-left ph-bold ph-lg"></i> <i class="ph-arrow-u-up-left ph-bold ph-lg"></i>
<template v-if="appearNote.repliesCount > 0"> <template v-if="appearNote.repliesCount > 0">
@ -107,7 +107,7 @@
ref="reactButton" ref="reactButton"
v-tooltip.noDelay.bottom="i18n.ts.reaction" v-tooltip.noDelay.bottom="i18n.ts.reaction"
class="button _button" class="button _button"
@click="react()" @click.stop="react()"
> >
<i class="ph-smiley ph-bold ph-lg"></i> <i class="ph-smiley ph-bold ph-lg"></i>
</button> </button>
@ -118,7 +118,7 @@
" "
ref="reactButton" ref="reactButton"
class="button _button reacted" class="button _button reacted"
@click="undoReact(appearNote)" @click.stop="undoReact(appearNote)"
v-tooltip.noDelay.bottom="i18n.ts.removeReaction" v-tooltip.noDelay.bottom="i18n.ts.removeReaction"
> >
<i class="ph-minus ph-bold ph-lg"></i> <i class="ph-minus ph-bold ph-lg"></i>
@ -128,7 +128,7 @@
ref="menuButton" ref="menuButton"
v-tooltip.noDelay.bottom="i18n.ts.more" v-tooltip.noDelay.bottom="i18n.ts.more"
class="button _button" class="button _button"
@click="menu()" @click.stop="menu()"
> >
<i class="ph-dots-three-outline ph-bold ph-lg"></i> <i class="ph-dots-three-outline ph-bold ph-lg"></i>
</button> </button>
@ -470,7 +470,6 @@ function noteClick(e) {
z-index: 2; z-index: 2;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
pointer-events: none; // Allow clicking anything w/out pointer-events: all; to open post
> :deep(.button) { > :deep(.button) {
position: relative; position: relative;
@ -484,7 +483,6 @@ function noteClick(e) {
max-width: 3.5em; max-width: 3.5em;
width: max-content; width: max-content;
min-width: max-content; min-width: max-content;
pointer-events: all;
height: auto; height: auto;
transition: opacity 0.2s; transition: opacity 0.2s;
&::before { &::before {

View File

@ -3,7 +3,7 @@
v-if="canRenote && $store.state.seperateRenoteQuote" v-if="canRenote && $store.state.seperateRenoteQuote"
v-tooltip.noDelay.bottom="i18n.ts.quote" v-tooltip.noDelay.bottom="i18n.ts.quote"
class="eddddedb _button" class="eddddedb _button"
@click="quote()" @click.stop="quote()"
> >
<i class="ph-quotes ph-bold ph-lg"></i> <i class="ph-quotes ph-bold ph-lg"></i>
</button> </button>

View File

@ -9,7 +9,7 @@
canToggle, canToggle,
newlyAdded: !isInitial, newlyAdded: !isInitial,
}" }"
@click="toggleReaction()" @click.stop="toggleReaction()"
> >
<XReactionIcon <XReactionIcon
class="icon" class="icon"
@ -100,13 +100,20 @@ useTooltip(
<style lang="scss" scoped> <style lang="scss" scoped>
.hkzvhatu { .hkzvhatu {
position: relative;
display: inline-block; display: inline-block;
height: 32px; height: 32px;
margin: 2px; margin-block: 2px;
padding: 0 6px; padding: 0 8px;
border-radius: 4px;
pointer-events: all; pointer-events: all;
min-width: max-content; min-width: max-content;
&::before {
content: "";
position: absolute;
inset: 0 2px;
border-radius: 4px;
z-index: -1;
}
&.newlyAdded { &.newlyAdded {
animation: scaleInSmall 0.3s cubic-bezier(0, 0, 0, 1.2); animation: scaleInSmall 0.3s cubic-bezier(0, 0, 0, 1.2);
:deep(.mk-emoji) { :deep(.mk-emoji) {
@ -126,9 +133,10 @@ useTooltip(
} }
} }
&.canToggle { &.canToggle {
&::before {
background: rgba(0, 0, 0, 0.05); background: rgba(0, 0, 0, 0.05);
}
&:hover { &:hover:not(.reacted)::before {
background: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.1);
} }
} }
@ -139,9 +147,7 @@ useTooltip(
&.reacted { &.reacted {
order: -1; order: -1;
background: var(--accent); &::before {
&:hover {
background: var(--accent); background: var(--accent);
} }

View File

@ -1,5 +1,9 @@
<template> <template>
<div ref="reactionsEl" class="reactions-list tdflqwzn" :class="{ isMe }"> <div
ref="reactionsEl"
class="reactions-list swiper-no-swiping tdflqwzn"
:class="{ isMe }"
>
<XReaction <XReaction
v-for="(count, reaction) in note.reactions" v-for="(count, reaction) in note.reactions"
:key="reaction" :key="reaction"
@ -50,6 +54,11 @@ const isMe = computed(() => $i && $i.id === props.note.userId);
transparent transparent
); );
scrollbar-width: none; scrollbar-width: none;
pointer-events: none;
:deep(*) {
pointer-events: all;
}
&::-webkit-scrollbar { &::-webkit-scrollbar {
display: none; display: none;
} }

View File

@ -5,7 +5,7 @@
v-tooltip.noDelay.bottom="i18n.ts.renote" v-tooltip.noDelay.bottom="i18n.ts.renote"
class="button _button canRenote" class="button _button canRenote"
:class="{ renoted: hasRenotedBefore }" :class="{ renoted: hasRenotedBefore }"
@click="renote(false, $event)" @click.stop="renote(false, $event)"
> >
<i class="ph-repeat ph-bold ph-lg"></i> <i class="ph-repeat ph-bold ph-lg"></i>
<p v-if="count > 0 && !detailedView" class="count">{{ count }}</p> <p v-if="count > 0 && !detailedView" class="count">{{ count }}</p>

View File

@ -2,7 +2,7 @@
<button <button
v-tooltip.noDelay.bottom="i18n.ts._gallery.like" v-tooltip.noDelay.bottom="i18n.ts._gallery.like"
class="button _button" class="button _button"
@click="star($event)" @click.stop="star($event)"
> >
<svg <svg
v-if="defaultStore.state.woozyMode === true" v-if="defaultStore.state.woozyMode === true"

View File

@ -4,7 +4,7 @@
class="button _button" class="button _button"
:class="$style.root" :class="$style.root"
ref="buttonRef" ref="buttonRef"
@click="toggleStar($event)" @click.stop="toggleStar($event)"
> >
<span v-if="!reacted"> <span v-if="!reacted">
<i <i

View File

@ -47,13 +47,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { import {
computed,
nextTick,
onMounted, onMounted,
onUnmounted, onUnmounted,
nextTick,
ref, ref,
watch,
computed,
toRefs, toRefs,
watch,
} from "vue"; } from "vue";
import { debounce } from "throttle-debounce"; import { debounce } from "throttle-debounce";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";

View File

@ -4,7 +4,7 @@
type="radio" type="radio"
:disabled="disabled" :disabled="disabled"
:checked="checked" :checked="checked"
v-on:change="(x) => toggle(x)" @change="(x) => toggle(x)"
/> />
<span class="button"> <span class="button">
<span></span> <span></span>
@ -26,7 +26,7 @@ const emit = defineEmits<{
(ev: "update:modelValue", value: any): void; (ev: "update:modelValue", value: any): void;
}>(); }>();
let checked = $computed(() => props.modelValue === props.value); const checked = $computed(() => props.modelValue === props.value);
function toggle(x) { function toggle(x) {
if (props.disabled) return; if (props.disabled) return;

View File

@ -12,7 +12,7 @@
:list="id" :list="id"
:value="modelValue" :value="modelValue"
:disabled="disabled" :disabled="disabled"
v-on:change="(x) => onChange(x)" @change="(x) => onChange(x)"
@focus="tooltipShow" @focus="tooltipShow"
@blur="tooltipHide" @blur="tooltipHide"
@touchstart="tooltipShow" @touchstart="tooltipShow"
@ -35,7 +35,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, defineAsyncComponent } from "vue"; import { computed, defineAsyncComponent, ref } from "vue";
import * as os from "@/os"; import * as os from "@/os";
const id = os.getUniqueId(); const id = os.getUniqueId();
@ -59,7 +59,7 @@ const props = withDefaults(
); );
const inputEl = ref<HTMLElement>(); const inputEl = ref<HTMLElement>();
let inputVal = $ref(props.modelValue); const inputVal = $ref(props.modelValue);
const emit = defineEmits<{ const emit = defineEmits<{
(ev: "update:modelValue", value: number): void; (ev: "update:modelValue", value: number): void;

View File

@ -43,15 +43,15 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { VNode } from "vue";
import { import {
onMounted,
nextTick,
ref,
watch,
computed, computed,
nextTick,
onMounted,
ref,
toRefs, toRefs,
VNode,
useSlots, useSlots,
watch,
} from "vue"; } from "vue";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";
import * as os from "@/os"; import * as os from "@/os";
@ -151,7 +151,7 @@ function show(ev: MouseEvent) {
opening.value = true; opening.value = true;
const menu = []; const menu = [];
let options = slots.default!(); const options = slots.default!();
const pushOption = (option: VNode) => { const pushOption = (option: VNode) => {
menu.push({ menu.push({

View File

@ -22,7 +22,8 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType, ref, watch } from "vue"; import type { PropType } from "vue";
import { defineComponent, ref, watch } from "vue";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";

View File

@ -4,7 +4,7 @@
type="checkbox" type="checkbox"
:checked="modelValue" :checked="modelValue"
:disabled="disabled" :disabled="disabled"
v-on:change="(x) => toggle(x)" @change="(x) => toggle(x)"
/> />
<div class="button"> <div class="button">
<div class="knob"></div> <div class="knob"></div>
@ -18,7 +18,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { Ref } from "vue"; import type { Ref } from "vue";
const props = defineProps<{ const props = defineProps<{
modelValue: boolean | Ref<boolean>; modelValue: boolean | Ref<boolean>;

View File

@ -39,14 +39,14 @@
<script lang="ts"> <script lang="ts">
import { import {
computed,
defineComponent, defineComponent,
nextTick,
onMounted, onMounted,
onUnmounted, onUnmounted,
nextTick,
ref, ref,
watch,
computed,
toRefs, toRefs,
watch,
} from "vue"; } from "vue";
import { debounce } from "throttle-debounce"; import { debounce } from "throttle-debounce";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";

View File

@ -10,7 +10,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
import { toUnicode } from "punycode/"; import { toUnicode } from "punycode/";
import { host as hostRaw } from "@/config"; import { host as hostRaw } from "@/config";

View File

@ -1,7 +1,7 @@
<template> <template>
<div <div
v-if="chosen && chosen.length > 0 && defaultStore.state.showAds"
v-for="chosenItem in chosen" v-for="chosenItem in chosen"
v-if="chosen && chosen.length > 0 && defaultStore.state.showAds"
class="qiivuoyo" class="qiivuoyo"
> >
<div v-if="!showMenu" class="main" :class="chosenItem.place"> <div v-if="!showMenu" class="main" :class="chosenItem.place">

View File

@ -37,7 +37,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, watch } from "vue"; import { onMounted, watch } from "vue";
import * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
import { getStaticImageUrl } from "@/scripts/get-static-image-url"; import { getStaticImageUrl } from "@/scripts/get-static-image-url";
import { extractAvgColorFromBlurhash } from "@/scripts/extract-avg-color-from-blurhash"; import { extractAvgColorFromBlurhash } from "@/scripts/extract-avg-color-from-blurhash";
import { acct, userPage } from "@/filters/user"; import { acct, userPage } from "@/filters/user";

View File

@ -22,7 +22,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref, watch } from "vue"; import { computed, ref, watch } from "vue";
import { CustomEmoji } from "calckey-js/built/entities"; import type { CustomEmoji } from "calckey-js/built/entities";
import { getStaticImageUrl } from "@/scripts/get-static-image-url"; import { getStaticImageUrl } from "@/scripts/get-static-image-url";
import { char2filePath } from "@/scripts/twemoji-base"; import { char2filePath } from "@/scripts/twemoji-base";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";

View File

@ -4,8 +4,8 @@
:plain="plain" :plain="plain"
:nowrap="nowrap" :nowrap="nowrap"
:author="author" :author="author"
:customEmojis="customEmojis" :custom-emojis="customEmojis"
:isNote="isNote" :is-note="isNote"
class="mfm-object" class="mfm-object"
:class="{ :class="{
nowrap, nowrap,

View File

@ -11,10 +11,10 @@
<div class="buttons"> <div class="buttons">
<button <button
v-if="displayBackButton" v-if="displayBackButton"
v-tooltip.noDelay="i18n.ts.goBack"
class="_buttonIcon button icon backButton" class="_buttonIcon button icon backButton"
@click.stop="goBack()" @click.stop="goBack()"
@touchstart="preventDrag" @touchstart="preventDrag"
v-tooltip.noDelay="i18n.ts.goBack"
> >
<i class="ph-caret-left ph-bold ph-lg"></i> <i class="ph-caret-left ph-bold ph-lg"></i>
</button> </button>
@ -23,7 +23,7 @@
class="avatar button" class="avatar button"
:user="$i" :user="$i"
:disable-preview="true" :disable-preview="true"
disableLink disable-link
@click.stop="openAccountMenu" @click.stop="openAccountMenu"
/> />
</div> </div>
@ -68,8 +68,8 @@
</div> </div>
<template v-if="metadata"> <template v-if="metadata">
<nav <nav
ref="tabsEl"
v-if="hasTabs" v-if="hasTabs"
ref="tabsEl"
class="tabs" class="tabs"
:class="{ collapse: hasTabs && tabs.length > 3 }" :class="{ collapse: hasTabs && tabs.length > 3 }"
> >
@ -123,14 +123,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { import {
computed, computed,
inject,
nextTick,
onMounted, onMounted,
onUnmounted, onUnmounted,
ref,
inject,
watch,
shallowReactive,
nextTick,
reactive, reactive,
ref,
shallowReactive,
watch,
} from "vue"; } from "vue";
import MkFollowButton from "@/components/MkFollowButton.vue"; import MkFollowButton from "@/components/MkFollowButton.vue";
import { popupMenu } from "@/os"; import { popupMenu } from "@/os";
@ -140,13 +140,13 @@ import { injectPageMetadata } from "@/scripts/page-metadata";
import { $i, openAccountMenu as openAccountMenu_ } from "@/account"; import { $i, openAccountMenu as openAccountMenu_ } from "@/account";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
type Tab = { interface Tab {
key?: string | null; key?: string | null;
title: string; title: string;
icon?: string; icon?: string;
iconOnly?: boolean; iconOnly?: boolean;
onClick?: (ev: MouseEvent) => void; onClick?: (ev: MouseEvent) => void;
}; }
const props = defineProps<{ const props = defineProps<{
tabs?: Tab[]; tabs?: Tab[];

View File

@ -24,10 +24,10 @@ const props = withDefaults(
}, },
); );
let ro: ResizeObserver; let ro: ResizeObserver,
let root = $ref<HTMLElement>(); root = $ref<HTMLElement>(),
let content = $ref<HTMLElement>(); content = $ref<HTMLElement>(),
let margin = $ref(0); margin = $ref(0);
const shouldSpacerMin = inject("shouldSpacerMin", false); const shouldSpacerMin = inject("shouldSpacerMin", false);
const adjust = (rect: { width: number; height: number }) => { const adjust = (rect: { width: number; height: number }) => {

View File

@ -16,14 +16,15 @@ const CURRENT_STICKY_TOP = "CURRENT_STICKY_TOP";
</script> </script>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, provide, inject, Ref, ref, watch } from "vue"; import type { Ref } from "vue";
import { inject, onMounted, onUnmounted, provide, ref, watch } from "vue";
const rootEl = $ref<HTMLElement>(); const rootEl = $ref<HTMLElement>();
const headerEl = $ref<HTMLElement>(); const headerEl = $ref<HTMLElement>();
const bodyEl = $ref<HTMLElement>(); const bodyEl = $ref<HTMLElement>();
let headerHeight = $ref<string | undefined>(); let headerHeight = $ref<string | undefined>(),
let childStickyTop = $ref(0); childStickyTop = $ref(0);
const parentStickyTop = inject<Ref<number>>(CURRENT_STICKY_TOP, ref(0)); const parentStickyTop = inject<Ref<number>>(CURRENT_STICKY_TOP, ref(0));
provide(CURRENT_STICKY_TOP, $$(childStickyTop)); provide(CURRENT_STICKY_TOP, $$(childStickyTop));

View File

@ -10,7 +10,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{

View File

@ -5,8 +5,8 @@
:is="currentPageComponent" :is="currentPageComponent"
:key="key" :key="key"
v-bind="Object.fromEntries(currentPageProps)" v-bind="Object.fromEntries(currentPageProps)"
tabindex="-1"
v-focus v-focus
tabindex="-1"
style="outline: none" style="outline: none"
/> />
@ -27,7 +27,7 @@ import {
provide, provide,
watch, watch,
} from "vue"; } from "vue";
import { Resolved, Router } from "@/nirax"; import type { Resolved, Router } from "@/nirax";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";
const props = defineProps<{ const props = defineProps<{
@ -56,9 +56,9 @@ function resolveNested(current: Resolved, d = 0): Resolved | null {
} }
const current = resolveNested(router.current)!; const current = resolveNested(router.current)!;
let currentPageComponent = $shallowRef(current.route.component); let currentPageComponent = $shallowRef(current.route.component),
let currentPageProps = $ref(current.props); currentPageProps = $ref(current.props),
let key = $ref( key = $ref(
current.route.path + JSON.stringify(Object.fromEntries(current.props)), current.route.path + JSON.stringify(Object.fromEntries(current.props)),
); );

View File

@ -222,7 +222,7 @@ const importPosts = async (ev) => {
const file = await selectFile(ev.currentTarget ?? ev.target); const file = await selectFile(ev.currentTarget ?? ev.target);
os.api("i/import-posts", { os.api("i/import-posts", {
fileId: file.id, fileId: file.id,
signatureCheck: importType.value === "mastodon" ? true : false, signatureCheck: false,
}) })
.then(onImportSuccess) .then(onImportSuccess)
.catch(onError); .catch(onError);

View File

@ -260,6 +260,15 @@ export function getUserMenu(user, router: Router = mainRouter) {
to: `/my/messaging/${Acct.toString(user)}`, to: `/my/messaging/${Acct.toString(user)}`,
} }
: undefined, : undefined,
user.host != null && user.url
? {
type: "a",
icon: "ph-arrow-square-out ph-bold ph-lg",
text: i18n.ts.showOnRemote,
href: user.url,
target: "_blank",
}
: undefined,
null, null,
{ {
icon: "ph-list-bullets ph-bold ph-lg", icon: "ph-list-bullets ph-bold ph-lg",

View File

@ -193,12 +193,12 @@ import {
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
import XCommon from "./_common_/common.vue"; import XCommon from "./_common_/common.vue";
import { import {
deckStore,
addColumn as addColumnToStore, addColumn as addColumnToStore,
loadDeck, deckStore,
getProfiles,
renameProfile as renameProfile_,
deleteProfile as deleteProfile_, deleteProfile as deleteProfile_,
getProfiles,
loadDeck,
renameProfile as renameProfile_,
} from "./deck/deck-store"; } from "./deck/deck-store";
import DeckColumnCore from "@/ui/deck/column-core.vue"; import DeckColumnCore from "@/ui/deck/column-core.vue";
import XSidebar from "@/ui/_common_/navbar.vue"; import XSidebar from "@/ui/_common_/navbar.vue";
@ -253,7 +253,7 @@ function showSettings() {
os.pageWindow("/settings/deck"); os.pageWindow("/settings/deck");
} }
let columnsEl = $ref<HTMLElement>(); const columnsEl = $ref<HTMLElement>();
const addColumn = async (ev) => { const addColumn = async (ev) => {
const columns = [ const columns = [

View File

@ -23,7 +23,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted } from "vue"; import { onMounted } from "vue";
import XColumn from "./column.vue"; import XColumn from "./column.vue";
import { updateColumn, Column } from "./deck-store"; import type { Column } from "./deck-store";
import { updateColumn } from "./deck-store";
import XTimeline from "@/components/MkTimeline.vue"; import XTimeline from "@/components/MkTimeline.vue";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
@ -38,7 +39,7 @@ const emit = defineEmits<{
(ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void; (ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void;
}>(); }>();
let timeline = $ref<InstanceType<typeof XTimeline>>(); const timeline = $ref<InstanceType<typeof XTimeline>>();
onMounted(() => { onMounted(() => {
if (props.column.antennaId == null) { if (props.column.antennaId == null) {

View File

@ -23,7 +23,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import XColumn from "./column.vue"; import XColumn from "./column.vue";
import { updateColumn, Column } from "./deck-store"; import type { Column } from "./deck-store";
import { updateColumn } from "./deck-store";
import XTimeline from "@/components/MkTimeline.vue"; import XTimeline from "@/components/MkTimeline.vue";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
@ -38,7 +39,7 @@ const emit = defineEmits<{
(ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void; (ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void;
}>(); }>();
let timeline = $ref<InstanceType<typeof XTimeline>>(); const timeline = $ref<InstanceType<typeof XTimeline>>();
if (props.column.channelId == null) { if (props.column.channelId == null) {
setChannel(); setChannel();

View File

@ -68,7 +68,7 @@ import XWidgetsColumn from "./widgets-column.vue";
import XMentionsColumn from "./mentions-column.vue"; import XMentionsColumn from "./mentions-column.vue";
import XDirectColumn from "./direct-column.vue"; import XDirectColumn from "./direct-column.vue";
import XChannelColumn from "./channel-column.vue"; import XChannelColumn from "./channel-column.vue";
import { Column } from "./deck-store"; import type { Column } from "./deck-store";
defineProps<{ defineProps<{
column?: Column; column?: Column;

View File

@ -56,23 +56,23 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onBeforeUnmount, onMounted, provide, Ref, watch } from "vue"; import { Ref, onBeforeUnmount, onMounted, provide, watch } from "vue";
import type { Column } from "./deck-store";
import { import {
updateColumn, deckStore,
popRightColumn,
removeColumn,
stackLeftColumn,
swapColumn,
swapDownColumn,
swapLeftColumn, swapLeftColumn,
swapRightColumn, swapRightColumn,
swapUpColumn, swapUpColumn,
swapDownColumn, updateColumn,
stackLeftColumn,
popRightColumn,
removeColumn,
swapColumn,
Column,
deckStore,
} from "./deck-store"; } from "./deck-store";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { MenuItem } from "@/types/menu"; import type { MenuItem } from "@/types/menu";
provide("shouldHeaderThin", true); provide("shouldHeaderThin", true);
provide("shouldOmitHeaderTitle", true); provide("shouldOmitHeaderTitle", true);
@ -99,15 +99,15 @@ const emit = defineEmits<{
(ev: "headerWheel", ctx: WheelEvent): void; (ev: "headerWheel", ctx: WheelEvent): void;
}>(); }>();
let body = $ref<HTMLDivElement>(); const body = $ref<HTMLDivElement>();
let dragging = $ref(false); let dragging = $ref(false);
watch($$(dragging), (v) => watch($$(dragging), (v) =>
os.deckGlobalEvents.emit(v ? "column.dragStart" : "column.dragEnd"), os.deckGlobalEvents.emit(v ? "column.dragStart" : "column.dragEnd"),
); );
let draghover = $ref(false); let draghover = $ref(false),
let dropready = $ref(false); dropready = $ref(false);
const isMainColumn = $computed(() => props.column.type === "main"); const isMainColumn = $computed(() => props.column.type === "main");
const active = $computed(() => props.column.active !== false); const active = $computed(() => props.column.active !== false);

View File

@ -20,6 +20,7 @@ export type Column = {
| "notifications" | "notifications"
| "tl" | "tl"
| "antenna" | "antenna"
| "channel"
| "list" | "list"
| "mentions" | "mentions"
| "direct"; | "direct";
@ -29,9 +30,10 @@ export type Column = {
active?: boolean; active?: boolean;
flexible?: boolean; flexible?: boolean;
antennaId?: string; antennaId?: string;
channelId?: string;
listId?: string; listId?: string;
includingTypes?: typeof notificationTypes[number][]; includingTypes?: typeof notificationTypes[number][];
tl?: "home" | "local" | "social" | "global"; tl?: "home" | "local" | "social" | "recommended" | "global";
}; };
export const deckStore = markRaw( export const deckStore = markRaw(

View File

@ -19,8 +19,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import XColumn from "./column.vue"; import XColumn from "./column.vue";
import type { Column } from "./deck-store";
import XNotes from "@/components/MkNotes.vue"; import XNotes from "@/components/MkNotes.vue";
import { Column } from "./deck-store";
defineProps<{ defineProps<{
column: Column; column: Column;

View File

@ -23,7 +23,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import XColumn from "./column.vue"; import XColumn from "./column.vue";
import { updateColumn, Column } from "./deck-store"; import type { Column } from "./deck-store";
import { updateColumn } from "./deck-store";
import XTimeline from "@/components/MkTimeline.vue"; import XTimeline from "@/components/MkTimeline.vue";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
@ -38,7 +39,7 @@ const emit = defineEmits<{
(ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void; (ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void;
}>(); }>();
let timeline = $ref<InstanceType<typeof XTimeline>>(); const timeline = $ref<InstanceType<typeof XTimeline>>();
if (props.column.listId == null) { if (props.column.listId == null) {
setList(); setList();

View File

@ -20,14 +20,16 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ComputedRef, provide } from "vue"; import type { ComputedRef } from "vue";
import { provide } from "vue";
import XColumn from "./column.vue"; import XColumn from "./column.vue";
import { deckStore, Column } from "@/ui/deck/deck-store"; import type { Column } from "@/ui/deck/deck-store";
import { deckStore } from "@/ui/deck/deck-store";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { mainRouter } from "@/router"; import { mainRouter } from "@/router";
import type { PageMetadata } from "@/scripts/page-metadata";
import { import {
PageMetadata,
provideMetadataReceiver, provideMetadataReceiver,
setPageMetadata, setPageMetadata,
} from "@/scripts/page-metadata"; } from "@/scripts/page-metadata";
@ -67,7 +69,7 @@ function onContextmenu(ev: MouseEvent) {
["INPUT", "TEXTAREA", "IMG", "VIDEO", "CANVAS"].includes( ["INPUT", "TEXTAREA", "IMG", "VIDEO", "CANVAS"].includes(
(ev.target as HTMLElement).tagName, (ev.target as HTMLElement).tagName,
) || ) ||
(ev.target as HTMLElement).attributes["contenteditable"] (ev.target as HTMLElement).attributes.contenteditable
) )
return; return;
if (window.getSelection()?.toString() !== "") return; if (window.getSelection()?.toString() !== "") return;

View File

@ -16,8 +16,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import XColumn from "./column.vue"; import XColumn from "./column.vue";
import type { Column } from "./deck-store";
import XNotes from "@/components/MkNotes.vue"; import XNotes from "@/components/MkNotes.vue";
import { Column } from "./deck-store";
defineProps<{ defineProps<{
column: Column; column: Column;

View File

@ -44,7 +44,7 @@ function func(): void {
done: async (res) => { done: async (res) => {
const { includingTypes } = res; const { includingTypes } = res;
updateColumn(props.column.id, { updateColumn(props.column.id, {
includingTypes: includingTypes, includingTypes,
}); });
}, },
}, },

View File

@ -46,7 +46,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted } from "vue"; import { onMounted } from "vue";
import XColumn from "./column.vue"; import XColumn from "./column.vue";
import { removeColumn, updateColumn, Column } from "./deck-store"; import type { Column } from "./deck-store";
import { removeColumn, updateColumn } from "./deck-store";
import XTimeline from "@/components/MkTimeline.vue"; import XTimeline from "@/components/MkTimeline.vue";
import * as os from "@/os"; import * as os from "@/os";
import { $i } from "@/account"; import { $i } from "@/account";
@ -63,9 +64,9 @@ const emit = defineEmits<{
(ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void; (ev: "parent-focus", direction: "up" | "down" | "left" | "right"): void;
}>(); }>();
let disabled = $ref(false); let disabled = $ref(false),
let indicated = $ref(false); indicated = $ref(false),
let columnActive = $ref(true); columnActive = $ref(true);
onMounted(() => { onMounted(() => {
if (props.column.tl == null) { if (props.column.tl == null) {

View File

@ -34,9 +34,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import XColumn from "./column.vue"; import XColumn from "./column.vue";
import type { Column } from "./deck-store";
import { import {
addColumnWidget, addColumnWidget,
Column,
removeColumnWidget, removeColumnWidget,
setColumnWidgets, setColumnWidgets,
updateColumnWidget, updateColumnWidget,

View File

@ -169,10 +169,10 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { defineAsyncComponent, provide, onMounted, computed, ref } from "vue"; import { computed, defineAsyncComponent, onMounted, provide, ref } from "vue";
import XCommon from "./_common_/common.vue";
import * as Acct from "calckey-js/built/acct"; import * as Acct from "calckey-js/built/acct";
import type { ComputedRef } from "vue"; import type { ComputedRef } from "vue";
import XCommon from "./_common_/common.vue";
import type { PageMetadata } from "@/scripts/page-metadata"; import type { PageMetadata } from "@/scripts/page-metadata";
import { instanceName, ui } from "@/config"; import { instanceName, ui } from "@/config";
import XDrawerMenu from "@/ui/_common_/navbar-for-mobile.vue"; import XDrawerMenu from "@/ui/_common_/navbar-for-mobile.vue";
@ -232,7 +232,7 @@ const menuIndicated = computed(() => {
}); });
function updateButtonState(): void { function updateButtonState(): void {
let routerState = window.location.pathname; const routerState = window.location.pathname;
if (routerState === "/") { if (routerState === "/") {
buttonAnimIndex.value = 0; buttonAnimIndex.value = 0;
return; return;
@ -246,7 +246,6 @@ function updateButtonState(): void {
return; return;
} }
buttonAnimIndex.value = 3; buttonAnimIndex.value = 3;
return;
} }
updateButtonState(); updateButtonState();
@ -358,7 +357,7 @@ const onContextmenu = (ev: MouseEvent) => {
["INPUT", "TEXTAREA", "IMG", "VIDEO", "CANVAS"].includes( ["INPUT", "TEXTAREA", "IMG", "VIDEO", "CANVAS"].includes(
ev.target.tagName, ev.target.tagName,
) || ) ||
ev.target.attributes["contenteditable"] ev.target.attributes.contenteditable
) )
return; return;
if (window.getSelection()?.toString() !== "") return; if (window.getSelection()?.toString() !== "") return;

View File

@ -39,8 +39,8 @@ const emit = defineEmits<{
(ev: "mounted", el: Element): void; (ev: "mounted", el: Element): void;
}>(); }>();
let editMode = $ref(false); const editMode = $ref(false);
let rootEl = $ref<HTMLDivElement>(); const rootEl = $ref<HTMLDivElement>();
onMounted(() => { onMounted(() => {
emit("mounted", rootEl); emit("mounted", rootEl);

View File

@ -4,7 +4,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, defineAsyncComponent } from "vue"; import { defineAsyncComponent, defineComponent } from "vue";
import DesignA from "./visitor/a.vue"; import DesignA from "./visitor/a.vue";
import DesignB from "./visitor/b.vue"; import DesignB from "./visitor/b.vue";
import XCommon from "./_common_/common.vue"; import XCommon from "./_common_/common.vue";

View File

@ -74,7 +74,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, defineAsyncComponent } from "vue"; import { defineAsyncComponent, defineComponent } from "vue";
import XHeader from "./header.vue"; import XHeader from "./header.vue";
import { host, instanceName } from "@/config"; import { host, instanceName } from "@/config";
import { search } from "@/scripts/search"; import { search } from "@/scripts/search";

View File

@ -71,7 +71,8 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ComputedRef, onMounted, provide } from "vue"; import type { ComputedRef } from "vue";
import { onMounted, provide } from "vue";
import XHeader from "./header.vue"; import XHeader from "./header.vue";
import XKanban from "./kanban.vue"; import XKanban from "./kanban.vue";
import { host, instanceName } from "@/config"; import { host, instanceName } from "@/config";
@ -84,8 +85,8 @@ import XSignupDialog from "@/components/MkSignupDialog.vue";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";
import { ColdDeviceStorage, defaultStore } from "@/store"; import { ColdDeviceStorage, defaultStore } from "@/store";
import { mainRouter } from "@/router"; import { mainRouter } from "@/router";
import type { PageMetadata } from "@/scripts/page-metadata";
import { import {
PageMetadata,
provideMetadataReceiver, provideMetadataReceiver,
setPageMetadata, setPageMetadata,
} from "@/scripts/page-metadata"; } from "@/scripts/page-metadata";
@ -111,10 +112,10 @@ const isTimelineAvailable =
!instance.disableLocalTimeline || !instance.disableLocalTimeline ||
!instance.disableRecommendedTimeline || !instance.disableRecommendedTimeline ||
!instance.disableGlobalTimeline; !instance.disableGlobalTimeline;
let showMenu = $ref(false); const showMenu = $ref(false);
let isDesktop = $ref(window.innerWidth >= DESKTOP_THRESHOLD); let isDesktop = $ref(window.innerWidth >= DESKTOP_THRESHOLD),
let narrow = $ref(window.innerWidth < 1280); narrow = $ref(window.innerWidth < 1280),
let meta = $ref(); meta = $ref();
const keymap = $computed(() => { const keymap = $computed(() => {
return { return {

View File

@ -81,7 +81,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, defineAsyncComponent } from "vue"; import { defineAsyncComponent, defineComponent } from "vue";
import { host, instanceName } from "@/config"; import { host, instanceName } from "@/config";
import * as os from "@/os"; import * as os from "@/os";
import MkPagination from "@/components/MkPagination.vue"; import MkPagination from "@/components/MkPagination.vue";

View File

@ -7,11 +7,12 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { provide, ComputedRef } from "vue"; import type { ComputedRef } from "vue";
import { provide } from "vue";
import XCommon from "./_common_/common.vue"; import XCommon from "./_common_/common.vue";
import { mainRouter } from "@/router"; import { mainRouter } from "@/router";
import type { PageMetadata } from "@/scripts/page-metadata";
import { import {
PageMetadata,
provideMetadataReceiver, provideMetadataReceiver,
setPageMetadata, setPageMetadata,
} from "@/scripts/page-metadata"; } from "@/scripts/page-metadata";

View File

@ -36,14 +36,14 @@ const props = defineProps<{
activity: any[]; activity: any[];
}>(); }>();
let viewBoxX: number = $ref(147); const viewBoxX: number = $ref(147);
let viewBoxY: number = $ref(60); const viewBoxY: number = $ref(60);
let zoom: number = $ref(1); let zoom: number = $ref(1),
let pos: number = $ref(0); pos: number = $ref(0),
let pointsNote: any = $ref(null); pointsNote: any = $ref(null),
let pointsReply: any = $ref(null); pointsReply: any = $ref(null),
let pointsRenote: any = $ref(null); pointsRenote: any = $ref(null),
let pointsTotal: any = $ref(null); pointsTotal: any = $ref(null);
function dragListen(fn) { function dragListen(fn) {
window.addEventListener("mousemove", fn); window.addEventListener("mousemove", fn);
@ -65,8 +65,8 @@ function onMousedown(ev) {
// //
dragListen((me) => { dragListen((me) => {
let moveLeft = me.clientX - clickX; const moveLeft = me.clientX - clickX;
let moveTop = me.clientY - clickY; const moveTop = me.clientY - clickY;
zoom = Math.max(1, baseZoom + -moveTop / 20); zoom = Math.max(1, baseZoom + -moveTop / 20);
pos = Math.min(0, basePos + moveLeft); pos = Math.min(0, basePos + moveLeft);

View File

@ -38,17 +38,16 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, reactive, ref, watch } from "vue"; import { onMounted, onUnmounted, reactive, ref, watch } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import XCalendar from "./activity.calendar.vue"; import XCalendar from "./activity.calendar.vue";
import XChart from "./activity.chart.vue"; import XChart from "./activity.chart.vue";
import MkHeatmap from "@/components/MkHeatmap.vue"; import MkHeatmap from "@/components/MkHeatmap.vue";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import * as os from "@/os"; import * as os from "@/os";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import { $i } from "@/account"; import { $i } from "@/account";

View File

@ -28,14 +28,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from "vue"; import { onMounted, onUnmounted, ref, watch } from "vue";
import { AiScript, parse, utils } from "@syuilo/aiscript"; import { AiScript, parse, utils } from "@syuilo/aiscript";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import * as os from "@/os"; import * as os from "@/os";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import { createAiScriptEnv } from "@/scripts/aiscript/api"; import { createAiScriptEnv } from "@/scripts/aiscript/api";

View File

@ -9,14 +9,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from "vue"; import { onMounted, onUnmounted, ref, watch } from "vue";
import { AiScript, parse, utils } from "@syuilo/aiscript"; import { AiScript, parse, utils } from "@syuilo/aiscript";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import * as os from "@/os"; import * as os from "@/os";
import { createAiScriptEnv } from "@/scripts/aiscript/api"; import { createAiScriptEnv } from "@/scripts/aiscript/api";
import { $i } from "@/account"; import { $i } from "@/account";

View File

@ -45,14 +45,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onUnmounted, ref } from "vue"; import { onUnmounted, ref } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { useInterval } from "@/scripts/use-interval"; import { useInterval } from "@/scripts/use-interval";
import { $i } from "@/account"; import { $i } from "@/account";

View File

@ -47,14 +47,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import MkAnalogClock from "@/components/MkAnalogClock.vue"; import MkAnalogClock from "@/components/MkAnalogClock.vue";
import MkDigitalClock from "@/components/MkDigitalClock.vue"; import MkDigitalClock from "@/components/MkDigitalClock.vue";

View File

@ -16,14 +16,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onUnmounted, ref, watch } from "vue"; import { onUnmounted, ref, watch } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import { timezones } from "@/scripts/timezones"; import { timezones } from "@/scripts/timezones";
import MkDigitalClock from "@/components/MkDigitalClock.vue"; import MkDigitalClock from "@/components/MkDigitalClock.vue";

View File

@ -49,14 +49,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref } from "vue"; import { onMounted, onUnmounted, ref } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import MkMiniChart from "@/components/MkMiniChart.vue"; import MkMiniChart from "@/components/MkMiniChart.vue";
import * as os from "@/os"; import * as os from "@/os";

View File

@ -22,9 +22,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import { import {
useWidgetPropsManager,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import type { Widget, WidgetComponentExpose } from "./widget"; import type { Widget, WidgetComponentExpose } from "./widget";
import type { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
@ -58,7 +58,7 @@ const { widgetProps, configure } = useWidgetPropsManager(
emit, emit,
); );
let cloud = $ref<InstanceType<typeof MkTagCloud> | null>(); const cloud = $ref<InstanceType<typeof MkTagCloud> | null>();
let activeInstances = $shallowRef(null); let activeInstances = $shallowRef(null);
function onInstanceClick(i) { function onInstanceClick(i) {

View File

@ -124,14 +124,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, reactive, ref } from "vue"; import { onMounted, onUnmounted, reactive, ref } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import { stream } from "@/stream"; import { stream } from "@/stream";
import number from "@/filters/number"; import number from "@/filters/number";
import * as sound from "@/scripts/sound"; import * as sound from "@/scripts/sound";

View File

@ -24,14 +24,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, reactive, ref, watch } from "vue"; import { onMounted, onUnmounted, reactive, ref, watch } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import * as os from "@/os"; import * as os from "@/os";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";

View File

@ -31,14 +31,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { defineAsyncComponent } from "vue"; import { defineAsyncComponent } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import XNotifications from "@/components/MkNotifications.vue"; import XNotifications from "@/components/MkNotifications.vue";
import * as os from "@/os"; import * as os from "@/os";

View File

@ -21,14 +21,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref } from "vue"; import { onMounted, onUnmounted, ref } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import * as os from "@/os"; import * as os from "@/os";
import { useInterval } from "@/scripts/use-interval"; import { useInterval } from "@/scripts/use-interval";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";

View File

@ -27,14 +27,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, reactive, ref } from "vue"; import { onMounted, onUnmounted, reactive, ref } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import { stream } from "@/stream"; import { stream } from "@/stream";
import { getStaticImageUrl } from "@/scripts/get-static-image-url"; import { getStaticImageUrl } from "@/scripts/get-static-image-url";
import * as os from "@/os"; import * as os from "@/os";

View File

@ -9,14 +9,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue"; import {} from "vue";
import { GetFormResultType } from "@/scripts/form"; import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import type { GetFormResultType } from "@/scripts/form";
import XPostForm from "@/components/MkPostForm.vue"; import XPostForm from "@/components/MkPostForm.vue";
const name = "postForm"; const name = "postForm";

View File

@ -38,15 +38,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from "vue"; import { onMounted, onUnmounted, ref, watch } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import MarqueeText from "@/components/MkMarquee.vue"; import MarqueeText from "@/components/MkMarquee.vue";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import * as os from "@/os"; import * as os from "@/os";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import { useInterval } from "@/scripts/use-interval"; import { useInterval } from "@/scripts/use-interval";

View File

@ -30,14 +30,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from "vue"; import { onMounted, onUnmounted, ref, watch } from "vue";
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import * as os from "@/os"; import * as os from "@/os";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import { useInterval } from "@/scripts/use-interval"; import { useInterval } from "@/scripts/use-interval";

View File

@ -30,14 +30,13 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { Widget, WidgetComponentExpose } from "./widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "./widget"; } from "./widget";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import { host } from "@/config"; import { host } from "@/config";
const name = "serverInfo"; const name = "serverInfo";

View File

@ -82,7 +82,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onBeforeUnmount } from "vue"; import { onBeforeUnmount, onMounted } from "vue";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
const props = defineProps<{ const props = defineProps<{
@ -90,23 +90,23 @@ const props = defineProps<{
meta: any; meta: any;
}>(); }>();
let viewBoxX: number = $ref(50); const viewBoxX: number = $ref(50);
let viewBoxY: number = $ref(30); const viewBoxY: number = $ref(30);
let stats: any[] = $ref([]); const stats: any[] = $ref([]);
const cpuGradientId = uuid(); const cpuGradientId = uuid();
const cpuMaskId = uuid(); const cpuMaskId = uuid();
const memGradientId = uuid(); const memGradientId = uuid();
const memMaskId = uuid(); const memMaskId = uuid();
let cpuPolylinePoints: string = $ref(""); let cpuPolylinePoints: string = $ref(""),
let memPolylinePoints: string = $ref(""); memPolylinePoints: string = $ref(""),
let cpuPolygonPoints: string = $ref(""); cpuPolygonPoints: string = $ref(""),
let memPolygonPoints: string = $ref(""); memPolygonPoints: string = $ref(""),
let cpuHeadX: any = $ref(null); cpuHeadX: any = $ref(null),
let cpuHeadY: any = $ref(null); cpuHeadY: any = $ref(null),
let memHeadX: any = $ref(null); memHeadX: any = $ref(null),
let memHeadY: any = $ref(null); memHeadY: any = $ref(null),
let cpuP: string = $ref(""); cpuP: string = $ref(""),
let memP: string = $ref(""); memP: string = $ref("");
onMounted(() => { onMounted(() => {
props.connection.on("stats", onStats); props.connection.on("stats", onStats);
@ -125,11 +125,11 @@ function onStats(connStats) {
stats.push(connStats); stats.push(connStats);
if (stats.length > 50) stats.shift(); if (stats.length > 50) stats.shift();
let cpuPolylinePointsStats = stats.map((s, i) => [ const cpuPolylinePointsStats = stats.map((s, i) => [
viewBoxX - (stats.length - 1 - i), viewBoxX - (stats.length - 1 - i),
(1 - s.cpu) * viewBoxY, (1 - s.cpu) * viewBoxY,
]); ]);
let memPolylinePointsStats = stats.map((s, i) => [ const memPolylinePointsStats = stats.map((s, i) => [
viewBoxX - (stats.length - 1 - i), viewBoxX - (stats.length - 1 - i),
(1 - s.mem.active / props.meta.mem.total) * viewBoxY, (1 - s.mem.active / props.meta.mem.total) * viewBoxY,
]); ]);

View File

@ -10,7 +10,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onBeforeUnmount } from "vue"; import { onBeforeUnmount, onMounted } from "vue";
import XPie from "./pie.vue"; import XPie from "./pie.vue";
const props = defineProps<{ const props = defineProps<{

View File

@ -51,12 +51,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref } from "vue"; import { onMounted, onUnmounted, ref } from "vue";
import type { Widget, WidgetComponentExpose } from "../widget";
import { import {
useWidgetPropsManager,
Widget,
WidgetComponentEmits, WidgetComponentEmits,
WidgetComponentExpose,
WidgetComponentProps, WidgetComponentProps,
useWidgetPropsManager,
} from "../widget"; } from "../widget";
import XCpuMemory from "./cpu-mem.vue"; import XCpuMemory from "./cpu-mem.vue";
import XNet from "./net.vue"; import XNet from "./net.vue";
@ -65,7 +64,7 @@ import XMemory from "./mem.vue";
import XDisk from "./disk.vue"; import XDisk from "./disk.vue";
import XMeili from "./meilisearch.vue"; import XMeili from "./meilisearch.vue";
import MkContainer from "@/components/MkContainer.vue"; import MkContainer from "@/components/MkContainer.vue";
import { GetFormResultType } from "@/scripts/form"; import type { GetFormResultType } from "@/scripts/form";
import * as os from "@/os"; import * as os from "@/os";
import { stream } from "@/stream"; import { stream } from "@/stream";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";

Some files were not shown because too many files have changed in this diff Show More