Merge branch 'develop' into repair-style

This commit is contained in:
Kainoa Kanter 2022-07-06 21:40:18 -07:00 committed by GitHub
commit a162526539
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 37 additions and 62 deletions

View file

@ -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

View file

@ -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",

View file

@ -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);
} }

View file

@ -53,7 +53,7 @@ html
block meta block meta
block og block og
meta(property='og:title' content= title || 'Misskey') meta(property='og:title' content= title || 'Misskey')
meta(property='og:description' content= desc || '✨🌎✨ A interplanetary communication platform ✨🚀✨') meta(property='og:description' content= desc || '✨🌎✨ A interplanetary communication platform ✨🚀✨')
meta(property='og:image' content= img) meta(property='og:image' content= img)

View file

@ -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<{

View file

@ -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>

View file

@ -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;

View file

@ -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 => {

View file

@ -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'));

View file

@ -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);

View file

@ -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);

View file

@ -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) {