Merge branch 'develop' into repair-style
This commit is contained in:
commit
a162526539
@ -28,6 +28,7 @@ You should also include the user name that made the change.
|
|||||||
- Client: Improve deck UI @syuilo
|
- Client: Improve deck UI @syuilo
|
||||||
- Client: Word mute also checks content warnings @Johann150
|
- Client: Word mute also checks content warnings @Johann150
|
||||||
- Client: メニューからページをリロードできるように @syuilo
|
- Client: メニューからページをリロードできるように @syuilo
|
||||||
|
- Client: Improve emoji picker performance @syuilo
|
||||||
- ユーザーにモデレーションメモを残せる機能 @syuilo
|
- ユーザーにモデレーションメモを残せる機能 @syuilo
|
||||||
- Make possible to delete an account by admin @syuilo
|
- Make possible to delete an account by admin @syuilo
|
||||||
- Improve player detection in URL preview @mei23
|
- Improve player detection in URL preview @mei23
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "12.112.0-beta.18",
|
"version": "12.112.0-beta.20",
|
||||||
"codename": "indigo",
|
"codename": "indigo",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -106,39 +106,15 @@
|
|||||||
function renderError(code, details) {
|
function renderError(code, details) {
|
||||||
let errorsElement = document.getElementById('errors');
|
let errorsElement = document.getElementById('errors');
|
||||||
if (!errorsElement) {
|
if (!errorsElement) {
|
||||||
document.getElementsByTagName("head")[0].insertAdjacentHTML(
|
|
||||||
"beforeend",
|
|
||||||
`<link rel="stylesheet" href="../error.css" />`);
|
|
||||||
document.documentElement.innerHTML = `
|
document.documentElement.innerHTML = `
|
||||||
<svg class="icon-warning" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-alert-triangle" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
<h1>⚠ An error has occurred. ⚠</h1>
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
<p>If the problem persists, please contact the administrator. You may also try the following options:</p>
|
||||||
<path d="M12 9v2m0 4v.01"></path>
|
<ul>
|
||||||
<path d="M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75"></path>
|
<li>Start <a href="/cli">the simple client</a></li>
|
||||||
</svg>
|
<li>Attempt to repair in <a href="/bios">BIOS</a></li>
|
||||||
<h1>An error has occurred!</h1>
|
<li><a href="/flush">Flush preferences and cache</a></li>
|
||||||
<button class="button-big" onclick="location.reload(true);">
|
</ul>
|
||||||
<span class="button-label-big">Refresh</span>
|
<hr>
|
||||||
</button>
|
|
||||||
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
|
|
||||||
<p>If the problem persists after refreshing, please contact your instance's administrator.<br>You may also try the following options:</p>
|
|
||||||
<a href="/flush">
|
|
||||||
<button class="button-small">
|
|
||||||
<span class="button-label-small">Flush preferences and cache</span>
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<a href="/cli">
|
|
||||||
<button class="button-small">
|
|
||||||
<span class="button-label-small">Start the simple client</span>
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<a href="/bios">
|
|
||||||
<button class="button-small">
|
|
||||||
<span class="button-label-small">Attempt to repair in Repair Tool</span>
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<div id="errors"></div>
|
<div id="errors"></div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -146,7 +122,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const detailsElement = document.createElement('details');
|
const detailsElement = document.createElement('details');
|
||||||
detailsElement.innerHTML = `<br><summary><code>ERROR CODE: ${code}</code></summary>${JSON.stringify(details)}`;
|
detailsElement.innerHTML = `<summary><code>ERROR CODE: ${code}</code></summary>${JSON.stringify(details)}`;
|
||||||
|
|
||||||
errorsElement.appendChild(detailsElement);
|
errorsElement.appendChild(detailsElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { Prism } from 'prismjs';
|
import Prism from 'prismjs';
|
||||||
import 'prismjs/themes/prism-okaidia.css';
|
import 'prismjs/themes/prism-okaidia.css';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
@ -59,11 +59,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div class="group">
|
<div v-once class="group">
|
||||||
<header class="_acrylic">{{ i18n.ts.customEmojis }}</header>
|
<header class="_acrylic">{{ i18n.ts.customEmojis }}</header>
|
||||||
<XSection v-for="category in customEmojiCategories" :key="'custom:' + category" :initial-shown="false" :emojis="customEmojis.filter(e => e.category === category).map(e => ':' + e.name + ':')" @chosen="chosen">{{ category || i18n.ts.other }}</XSection>
|
<XSection v-for="category in customEmojiCategories" :key="'custom:' + category" :initial-shown="false" :emojis="customEmojis.filter(e => e.category === category).map(e => ':' + e.name + ':')" @chosen="chosen">{{ category || i18n.ts.other }}</XSection>
|
||||||
</div>
|
</div>
|
||||||
<div class="group">
|
<div v-once class="group">
|
||||||
<header class="_acrylic">{{ i18n.ts.emoji }}</header>
|
<header class="_acrylic">{{ i18n.ts.emoji }}</header>
|
||||||
<XSection v-for="category in categories" :key="category" :emojis="emojilist.filter(e => e.category === category).map(e => e.char)" @chosen="chosen">{{ category }}</XSection>
|
<XSection v-for="category in categories" :key="category" :emojis="emojilist.filter(e => e.category === category).map(e => e.char)" @chosen="chosen">{{ category }}</XSection>
|
||||||
</div>
|
</div>
|
||||||
|
@ -136,7 +136,7 @@ function focusDown() {
|
|||||||
> .item {
|
> .item {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 6px 18px;
|
padding: 6px 16px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<div class="tbhwbxda">
|
<div class="tbhwbxda">
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<FormSplit :min-width="170">
|
<FormSplit :min-width="170">
|
||||||
<MkInput ref="usernameEl" v-model="username" @update:modelValue="search">
|
<MkInput v-model="username" :autofocus="true" @update:modelValue="search">
|
||||||
<template #label>{{ $ts.username }}</template>
|
<template #label>{{ $ts.username }}</template>
|
||||||
<template #prefix>@</template>
|
<template #prefix>@</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
@ -70,15 +70,8 @@ let host = $ref('');
|
|||||||
let users: misskey.entities.UserDetailed[] = $ref([]);
|
let users: misskey.entities.UserDetailed[] = $ref([]);
|
||||||
let recentUsers: misskey.entities.UserDetailed[] = $ref([]);
|
let recentUsers: misskey.entities.UserDetailed[] = $ref([]);
|
||||||
let selected: misskey.entities.UserDetailed | null = $ref(null);
|
let selected: misskey.entities.UserDetailed | null = $ref(null);
|
||||||
let usernameEl: HTMLElement = $ref();
|
|
||||||
let dialogEl = $ref();
|
let dialogEl = $ref();
|
||||||
|
|
||||||
const focus = () => {
|
|
||||||
if (usernameEl) {
|
|
||||||
usernameEl.focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const search = () => {
|
const search = () => {
|
||||||
if (username === '' && host === '') {
|
if (username === '' && host === '') {
|
||||||
users = [];
|
users = [];
|
||||||
@ -112,12 +105,6 @@ const cancel = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
focus();
|
|
||||||
|
|
||||||
nextTick(() => {
|
|
||||||
focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
os.api('users/show', {
|
os.api('users/show', {
|
||||||
userIds: defaultStore.state.recentlyUsedUsers,
|
userIds: defaultStore.state.recentlyUsedUsers,
|
||||||
}).then(users => {
|
}).then(users => {
|
||||||
|
@ -97,7 +97,10 @@ const darkThemeId = computed({
|
|||||||
return darkTheme.value.id;
|
return darkTheme.value.id;
|
||||||
},
|
},
|
||||||
set(id) {
|
set(id) {
|
||||||
ColdDeviceStorage.set('darkTheme', themes.value.find(x => x.id === id));
|
const t = themes.value.find(x => x.id === id);
|
||||||
|
if (t) { // テーマエディタでテーマを作成したときなどは、themesに反映されないため undefined になる
|
||||||
|
ColdDeviceStorage.set('darkTheme', t);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const lightTheme = ColdDeviceStorage.ref('lightTheme');
|
const lightTheme = ColdDeviceStorage.ref('lightTheme');
|
||||||
@ -106,7 +109,10 @@ const lightThemeId = computed({
|
|||||||
return lightTheme.value.id;
|
return lightTheme.value.id;
|
||||||
},
|
},
|
||||||
set(id) {
|
set(id) {
|
||||||
ColdDeviceStorage.set('lightTheme', themes.value.find(x => x.id === id));
|
const t = themes.value.find(x => x.id === id);
|
||||||
|
if (t) { // テーマエディタでテーマを作成したときなどは、themesに反映されないため undefined になる
|
||||||
|
ColdDeviceStorage.set('lightTheme', t);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
|
const darkMode = computed(defaultStore.makeGetterSetter('darkMode'));
|
||||||
|
@ -192,7 +192,7 @@ async function saveAs() {
|
|||||||
theme.name = name;
|
theme.name = name;
|
||||||
theme.author = `@${$i.username}@${toUnicode(host)}`;
|
theme.author = `@${$i.username}@${toUnicode(host)}`;
|
||||||
if (description) theme.desc = description;
|
if (description) theme.desc = description;
|
||||||
addTheme(theme);
|
await addTheme(theme);
|
||||||
applyTheme(theme);
|
applyTheme(theme);
|
||||||
if (defaultStore.state.darkMode) {
|
if (defaultStore.state.darkMode) {
|
||||||
ColdDeviceStorage.set('darkTheme', theme);
|
ColdDeviceStorage.set('darkTheme', theme);
|
||||||
|
@ -2,12 +2,8 @@ type ScrollBehavior = 'auto' | 'smooth' | 'instant';
|
|||||||
|
|
||||||
export function getScrollContainer(el: HTMLElement | null): HTMLElement | null {
|
export function getScrollContainer(el: HTMLElement | null): HTMLElement | null {
|
||||||
if (el == null || el.tagName === 'HTML') return null;
|
if (el == null || el.tagName === 'HTML') return null;
|
||||||
const overflow = window.getComputedStyle(el).getPropertyValue('overflow');
|
const overflow = window.getComputedStyle(el).getPropertyValue('overflow-y');
|
||||||
if (
|
if (overflow === 'scroll' || overflow === 'auto') {
|
||||||
// xとyを個別に指定している場合、`hidden scroll`みたいな値になる
|
|
||||||
overflow.endsWith('scroll') ||
|
|
||||||
overflow.endsWith('auto')
|
|
||||||
) {
|
|
||||||
return el;
|
return el;
|
||||||
} else {
|
} else {
|
||||||
return getScrollContainer(el.parentElement);
|
return getScrollContainer(el.parentElement);
|
||||||
|
@ -304,6 +304,14 @@ export class ColdDeviceStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static set<T extends keyof typeof ColdDeviceStorage.default>(key: T, value: typeof ColdDeviceStorage.default[T]): void {
|
public static set<T extends keyof typeof ColdDeviceStorage.default>(key: T, value: typeof ColdDeviceStorage.default[T]): void {
|
||||||
|
// 呼び出し側のバグ等で undefined が来ることがある
|
||||||
|
// undefined を文字列として localStorage に入れると参照する際の JSON.parse でコケて不具合の元になるため無視
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
if (value === undefined) {
|
||||||
|
console.error(`attempt to store undefined value for key '${key}'`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
localStorage.setItem(PREFIX + key, JSON.stringify(value));
|
localStorage.setItem(PREFIX + key, JSON.stringify(value));
|
||||||
|
|
||||||
for (const watcher of this.watchers) {
|
for (const watcher of this.watchers) {
|
||||||
|
Loading…
Reference in New Issue
Block a user