Merge branch 'develop' into toggle-ads

This commit is contained in:
Kainoa Kanter 2022-07-14 17:48:59 -07:00 committed by GitHub
commit e15be5ce08
25 changed files with 183 additions and 169 deletions

View File

@ -9,6 +9,13 @@
You should also include the user name that made the change.
-->
## 12.x.x (unreleased)
### Improvements
### Bugfixes
- クライアントが起動しなくなることがある問題を修正 @syuilo
## 12.113.0 (2022/07/13)
### Improvements

View File

@ -888,6 +888,7 @@ enableAutoSensitive: "自動NSFW判定"
enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。"
activeEmailValidationDescription: "ユーザーのメールアドレスのバリデーションを、捨てアドかどうかや実際に通信可能かどうかなどを判定しより積極的に行います。オフにすると単に文字列として正しいかどうかのみチェックされます。"
showAds: "広告を表示する"
navbar: "ナビゲーションバー"
_sensitiveMediaDetection:
description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。"

View File

@ -1,6 +1,6 @@
{
"name": "misskey",
"version": "12.113.0",
"version": "12.114.0-beta.6",
"codename": "indigo",
"repository": {
"type": "git",

View File

@ -14,9 +14,11 @@
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
(async () => {
window.onerror = (e) => {
console.error(e);
renderError('SOMETHING_HAPPENED', e);
};
window.onunhandledrejection = (e) => {
console.error(e);
renderError('SOMETHING_HAPPENED_IN_PROMISE', e);
};
@ -47,18 +49,30 @@
localStorage.setItem('localeVersion', v);
} else {
await checkUpdate();
renderError('LOCALE_FETCH_FAILED');
renderError('LOCALE_FETCH');
return;
}
}
//#endregion
//#region Script
import(`/assets/${CLIENT_ENTRY}`)
.catch(async e => {
await checkUpdate();
renderError('APP_FETCH_FAILED', e);
})
function importAppScript() {
import(`/assets/${CLIENT_ENTRY}`)
.catch(async e => {
await checkUpdate();
console.error(e);
renderError('APP_IMPORT', e);
});
}
// タイミングによっては、この時点でDOMの構築が済んでいる場合とそうでない場合とがある
if (document.readyState !== 'loading') {
importAppScript();
} else {
window.addEventListener('DOMContentLoaded', () => {
importAppScript();
});
}
//#endregion
//#region Theme
@ -112,35 +126,35 @@
let errorsElement = document.getElementById('errors');
if (!errorsElement) {
document.documentElement.innerHTML = `
document.body.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">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 9v2m0 4v.01"></path>
<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>
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 9v2m0 4v.01"></path>
<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>
</svg>
<h1>An error has occurred!</h1>
<button class="button-big" onclick="location.reload(true);">
<span class="button-label-big">Refresh</span>
</button>
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
<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">Clear preferences and cache</span>
</button>
</a>
<a href="/flush">
<button class="button-small">
<span class="button-label-small">Clear 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>
<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">Start the repair tool</span>
</button>
</a>
<a href="/bios">
<button class="button-small">
<span class="button-label-small">Start the repair tool</span>
</button>
</a>
<br>
<div id="errors"></div>
`;
@ -269,17 +283,22 @@
// eslint-disable-next-line no-inner-declarations
async function checkUpdate() {
// TODO: サーバーが落ちている場合などのエラーハンドリング
const res = await fetch('/api/meta', {
method: 'POST',
cache: 'no-cache'
});
try {
const res = await fetch('/api/meta', {
method: 'POST',
cache: 'no-cache'
});
const meta = await res.json();
const meta = await res.json();
if (meta.version != v) {
localStorage.setItem('v', meta.version);
refresh();
if (meta.version != v) {
localStorage.setItem('v', meta.version);
refresh();
}
} catch (e) {
console.error(e);
renderError('UPDATE_CHECK', e);
throw e;
}
}

View File

@ -56,7 +56,6 @@
"random-seed": "0.3.0",
"reflect-metadata": "0.1.13",
"rndstr": "1.0.0",
"rollup": "2.76.0",
"s-age": "1.1.2",
"sass": "1.53.0",
"seedrandom": "3.0.5",
@ -102,6 +101,7 @@
"@types/ws": "8.5.3",
"@typescript-eslint/eslint-plugin": "5.30.6",
"@typescript-eslint/parser": "5.30.6",
"rollup": "2.76.0",
"cross-env": "7.0.3",
"cypress": "10.3.0",
"eslint": "8.19.0",

View File

@ -16,9 +16,7 @@
</template>
<script lang="ts" setup>
import { useCssModule } from 'vue';
useCssModule();
import { } from 'vue';
const props = withDefaults(defineProps<{
inline?: boolean;

View File

@ -36,7 +36,7 @@
<script lang="ts" setup>
import { } from 'vue';
import MkModal from '@/components/ui/modal.vue';
import { menuDef } from '@/menu';
import { navbarItemDef } from '@/navbar';
import { instanceName } from '@/config';
import { defaultStore } from '@/store';
import { i18n } from '@/i18n';
@ -62,7 +62,7 @@ const modal = $ref<InstanceType<typeof MkModal>>();
const menu = defaultStore.state.menu;
const items = Object.keys(menuDef).filter(k => !menu.includes(k)).map(k => menuDef[k]).filter(def => def.show == null ? true : def.show).map(def => ({
const items = Object.keys(navbarItemDef).filter(k => !menu.includes(k)).map(k => navbarItemDef[k]).filter(def => def.show == null ? true : def.show).map(def => ({
type: def.to ? 'link' : 'button',
text: i18n.ts[def.title],
icon: def.icon,

View File

@ -16,7 +16,7 @@
<script lang="ts" setup>
import { toUnicode } from 'punycode';
import { useCssModule } from 'vue';
import { } from 'vue';
import tinycolor from 'tinycolor2';
import { host as localHost } from '@/config';
import { $i } from '@/account';
@ -37,8 +37,6 @@ const isMe = $i && (
const bg = tinycolor(getComputedStyle(document.documentElement).getPropertyValue(isMe ? '--mentionMe' : '--mention'));
bg.setAlpha(0.1);
const bgCss = bg.toRgbString();
useCssModule();
</script>
<style lang="scss" scoped>

View File

@ -116,7 +116,7 @@ const setPosition = () => {
let top: number;
if (props.targetElement) {
left = (rect.left + window.pageXOffset) + props.innerMargin;
left = (rect.left + props.targetElement.offsetWidth + window.pageXOffset) + props.innerMargin;
top = rect.top + window.pageYOffset + (props.targetElement.offsetHeight / 2);
} else {
left = props.x + props.innerMargin;

View File

@ -8,7 +8,6 @@ import tooltip from './tooltip';
import hotkey from './hotkey';
import appear from './appear';
import anim from './anim';
import stickyContainer from './sticky-container';
import clickAnime from './click-anime';
import panel from './panel';
import adaptiveBorder from './adaptive-border';
@ -24,7 +23,6 @@ export default function(app: App) {
app.directive('appear', appear);
app.directive('anim', anim);
app.directive('click-anime', clickAnime);
app.directive('sticky-container', stickyContainer);
app.directive('panel', panel);
app.directive('adaptive-border', adaptiveBorder);
}

View File

@ -1,17 +0,0 @@
import { Directive } from 'vue';
export default {
mounted(src, binding, vn) {
//const query = binding.value;
const header = src.children[0];
const body = src.children[1];
const currentStickyTop = getComputedStyle(src).getPropertyValue('--stickyTop') || '0px';
src.style.setProperty('--stickyTop', `calc(${currentStickyTop} + ${header.offsetHeight}px)`);
if (body) body.dataset.stickyContainerHeaderHeight = header.offsetHeight.toString();
header.style.setProperty('--stickyTop', currentStickyTop);
header.style.position = 'sticky';
header.style.top = 'var(--stickyTop)';
header.style.zIndex = '1';
},
} as Directive;

View File

@ -6,7 +6,7 @@ import { i18n } from '@/i18n';
import { ui } from '@/config';
import { unisonReload } from '@/scripts/unison-reload';
export const menuDef = reactive({
export const navbarItemDef = reactive({
notifications: {
title: 'notifications',
icon: 'fas fa-bell',

View File

@ -114,15 +114,15 @@ const menuDef = computed(() => [{
to: '/settings/theme',
active: props.initialPage === 'theme',
}, {
icon: 'fas fa-list-ul',
icon: 'fas fa-bars',
text: i18n.ts.navbar,
to: '/settings/navbar',
active: props.initialPage === 'navbar',
}, {
icon: 'fas fa-bars-progress',
text: i18n.ts.statusbar,
to: '/settings/statusbars',
active: props.initialPage === 'statusbars',
}, {
icon: 'fas fa-list-ul',
text: i18n.ts.menu,
to: '/settings/menu',
active: props.initialPage === 'menu',
}, {
icon: 'fas fa-music',
text: i18n.ts.sounds,
@ -225,7 +225,7 @@ const component = computed(() => {
case 'theme': return defineAsyncComponent(() => import('./theme.vue'));
case 'theme/install': return defineAsyncComponent(() => import('./theme.install.vue'));
case 'theme/manage': return defineAsyncComponent(() => import('./theme.manage.vue'));
case 'menu': return defineAsyncComponent(() => import('./menu.vue'));
case 'navbar': return defineAsyncComponent(() => import('./navbar.vue'));
case 'statusbars': return defineAsyncComponent(() => import('./statusbars.vue'));
case 'sounds': return defineAsyncComponent(() => import('./sounds.vue'));
case 'custom-css': return defineAsyncComponent(() => import('./custom-css.vue'));
@ -291,6 +291,8 @@ const headerActions = $computed(() => []);
const headerTabs = $computed(() => []);
definePageMetadata(INFO);
// w 890
// h 700
</script>
<style lang="scss" scoped>

View File

@ -1,7 +1,7 @@
<template>
<div class="_formRoot">
<FormTextarea v-model="items" tall manual-save class="_formBlock">
<template #label>{{ i18n.ts.menu }}</template>
<template #label>{{ i18n.ts.navbar }}</template>
<template #caption><button class="_textButton" @click="addItem">{{ i18n.ts.addItem }}</button></template>
</FormTextarea>
@ -23,7 +23,7 @@ import FormTextarea from '@/components/form/textarea.vue';
import FormRadios from '@/components/form/radios.vue';
import FormButton from '@/components/ui/button.vue';
import * as os from '@/os';
import { menuDef } from '@/menu';
import { navbarItemDef } from '@/navbar';
import { defaultStore } from '@/store';
import { unisonReload } from '@/scripts/unison-reload';
import { i18n } from '@/i18n';
@ -45,11 +45,11 @@ async function reloadAsk() {
}
async function addItem() {
const menu = Object.keys(menuDef).filter(k => !defaultStore.state.menu.includes(k));
const menu = Object.keys(navbarItemDef).filter(k => !defaultStore.state.menu.includes(k));
const { canceled, result: item } = await os.select({
title: i18n.ts.addItem,
items: [...menu.map(k => ({
value: k, text: i18n.ts[menuDef[k].title],
value: k, text: i18n.ts[navbarItemDef[k].title],
})), {
value: '-', text: i18n.ts.divider,
}],
@ -81,7 +81,7 @@ const headerActions = $computed(() => []);
const headerTabs = $computed(() => []);
definePageMetadata({
title: i18n.ts.menu,
title: i18n.ts.navbar,
icon: 'fas fa-list-ul',
});
</script>

View File

@ -12,7 +12,7 @@
<FormSection>
<template #label>{{ i18n.ts.signinHistory }}</template>
<MkPagination :pagination="pagination">
<MkPagination :pagination="pagination" disable-auto-load>
<template #default="{items}">
<div>
<div v-for="item in items" :key="item.id" v-panel class="timnmucd">

View File

@ -86,7 +86,6 @@ import FormRadios from '@/components/form/radios.vue';
import FormButton from '@/components/ui/button.vue';
import FormRange from '@/components/form/range.vue';
import * as os from '@/os';
import { menuDef } from '@/menu';
import { defaultStore } from '@/store';
import { i18n } from '@/i18n';

View File

@ -1,12 +1,14 @@
<template>
<div v-sticky-container class="yrzkoczt">
<MkTab v-model="include" class="tab">
<option :value="null">{{ $ts.notes }}</option>
<option value="replies">{{ $ts.notesAndReplies }}</option>
<option value="files">{{ $ts.withFiles }}</option>
</MkTab>
<MkStickyContainer>
<template #header>
<MkTab v-model="include" :class="$style.tab">
<option :value="null">{{ $ts.notes }}</option>
<option value="replies">{{ $ts.notesAndReplies }}</option>
<option value="files">{{ $ts.withFiles }}</option>
</MkTab>
</template>
<XNotes :no-gap="true" :pagination="pagination"/>
</div>
</MkStickyContainer>
</template>
<script lang="ts" setup>
@ -33,12 +35,10 @@ const pagination = {
};
</script>
<style lang="scss" scoped>
.yrzkoczt {
> .tab {
margin: calc(var(--margin) / 2) 0;
padding: calc(var(--margin) / 2) 0;
background: var(--bg);
}
<style lang="scss" module>
.tab {
margin: calc(var(--margin) / 2) 0;
padding: calc(var(--margin) / 2) 0;
background: var(--bg);
}
</style>

View File

@ -9,9 +9,9 @@
</MkA>
<template v-for="item in menu">
<div v-if="item === '-'" class="divider"></div>
<component :is="menuDef[item].to ? 'MkA' : 'button'" v-else-if="menuDef[item] && (menuDef[item].show !== false)" v-click-anime class="item _button" :class="[item, { active: menuDef[item].active }]" active-class="active" :to="menuDef[item].to" v-on="menuDef[item].action ? { click: menuDef[item].action } : {}">
<i class="icon fa-fw" :class="menuDef[item].icon"></i><span class="text">{{ $ts[menuDef[item].title] }}</span>
<span v-if="menuDef[item].indicated" class="indicator"><i class="icon fas fa-circle"></i></span>
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime class="item _button" :class="[item, { active: navbarItemDef[item].active }]" active-class="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
<i class="icon fa-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ $ts[navbarItemDef[item].title] }}</span>
<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="icon fas fa-circle"></i></span>
</component>
</template>
<div class="divider"></div>
@ -37,7 +37,7 @@ import { computed, defineAsyncComponent, defineComponent, ref, toRef, watch } fr
import { host } from '@/config';
import { search } from '@/scripts/search';
import * as os from '@/os';
import { menuDef } from '@/menu';
import { navbarItemDef } from '@/navbar';
import { openAccountMenu } from '@/account';
import { defaultStore } from '@/store';
@ -45,9 +45,9 @@ export default defineComponent({
setup(props, context) {
const menu = toRef(defaultStore.state, 'menu');
const otherMenuItemIndicated = computed(() => {
for (const def in menuDef) {
for (const def in navbarItemDef) {
if (menu.value.includes(def)) continue;
if (menuDef[def].indicated) return true;
if (navbarItemDef[def].indicated) return true;
}
return false;
});
@ -57,7 +57,7 @@ export default defineComponent({
accounts: [],
connection: null,
menu,
menuDef: menuDef,
navbarItemDef: navbarItemDef,
otherMenuItemIndicated,
post: os.post,
search,

View File

@ -4,29 +4,38 @@
<button v-click-anime class="item _button account" @click="openAccountMenu">
<MkAvatar :user="$i" class="avatar"/><MkAcct class="text" :user="$i"/>
</button>
<MkA v-click-anime class="item index" active-class="active" to="/" exact>
<i class="icon fas fa-home fa-fw"></i><span class="text">{{ $ts.timeline }}</span>
<MkA v-click-anime v-tooltip.right="i18n.ts.timeline" class="item index" active-class="active" to="/" exact>
<i class="icon fas fa-home fa-fw"></i><span class="text">{{ i18n.ts.timeline }}</span>
</MkA>
<template v-for="item in menu">
<div v-if="item === '-'" class="divider"></div>
<component :is="menuDef[item].to ? 'MkA' : 'button'" v-else-if="menuDef[item] && (menuDef[item].show !== false)" v-click-anime class="item _button" :class="[item, { active: menuDef[item].active }]" active-class="active" :to="menuDef[item].to" v-on="menuDef[item].action ? { click: menuDef[item].action } : {}">
<i class="icon fa-fw" :class="menuDef[item].icon"></i><span class="text">{{ $ts[menuDef[item].title] }}</span>
<span v-if="menuDef[item].indicated" class="indicator"><i class="icon fas fa-circle"></i></span>
<component
:is="navbarItemDef[item].to ? 'MkA' : 'button'"
v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)"
v-click-anime v-tooltip.right="i18n.ts[navbarItemDef[item].title]"
class="item _button"
:class="[item, { active: navbarItemDef[item].active }]"
active-class="active"
:to="navbarItemDef[item].to"
v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}"
>
<i class="icon fa-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ i18n.ts[navbarItemDef[item].title] }}</span>
<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="icon fas fa-circle"></i></span>
</component>
</template>
<div class="divider"></div>
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime class="item" active-class="active" to="/admin">
<i class="icon fas fa-door-open fa-fw"></i><span class="text">{{ $ts.controlPanel }}</span>
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip.right="i18n.ts.controlPanel" class="item" active-class="active" to="/admin">
<i class="icon fas fa-door-open fa-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
</MkA>
<button v-click-anime class="item _button" @click="more">
<i class="icon fa fa-ellipsis-h fa-fw"></i><span class="text">{{ $ts.more }}</span>
<i class="icon fa fa-ellipsis-h fa-fw"></i><span class="text">{{ i18n.ts.more }}</span>
<span v-if="otherMenuItemIndicated" class="indicator"><i class="icon fas fa-circle"></i></span>
</button>
<MkA v-click-anime class="item" active-class="active" to="/settings">
<i class="icon fas fa-cog fa-fw"></i><span class="text">{{ $ts.settings }}</span>
<MkA v-click-anime v-tooltip.right="i18n.ts.settings" class="item" active-class="active" to="/settings">
<i class="icon fas fa-cog fa-fw"></i><span class="text">{{ i18n.ts.settings }}</span>
</MkA>
<button class="item _button post" data-cy-open-post-form @click="os.post">
<i class="icon fas fa-pencil-alt fa-fw"></i><span class="text">{{ $ts.note }}</span>
<i class="icon fas fa-pencil-alt fa-fw"></i><span class="text">{{ i18n.ts.note }}</span>
</button>
</div>
</div>
@ -35,17 +44,18 @@
<script lang="ts" setup>
import { computed, defineAsyncComponent, ref, watch } from 'vue';
import * as os from '@/os';
import { menuDef } from '@/menu';
import { navbarItemDef } from '@/navbar';
import { $i, openAccountMenu as openAccountMenu_ } from '@/account';
import { defaultStore } from '@/store';
import { i18n } from '@/i18n';
const iconOnly = ref(false);
const menu = computed(() => defaultStore.state.menu);
const otherMenuItemIndicated = computed(() => {
for (const def in menuDef) {
for (const def in navbarItemDef) {
if (menu.value.includes(def)) continue;
if (menuDef[def].indicated) return true;
if (navbarItemDef[def].indicated) return true;
}
return false;
});
@ -244,7 +254,7 @@ function more(ev: MouseEvent) {
padding: 18px 0;
width: 100%;
text-align: center;
font-size: $ui-font-size * 1.1;
font-size: $ui-font-size;
line-height: initial;
> .icon,

View File

@ -7,9 +7,9 @@
</MkA>
<template v-for="item in menu">
<div v-if="item === '-'" class="divider"></div>
<component :is="menuDef[item].to ? 'MkA' : 'button'" v-else-if="menuDef[item] && (menuDef[item].show !== false)" v-click-anime v-tooltip="$ts[menuDef[item].title]" class="item _button" :class="item" active-class="active" :to="menuDef[item].to" v-on="menuDef[item].action ? { click: menuDef[item].action } : {}">
<i class="fa-fw" :class="menuDef[item].icon"></i>
<span v-if="menuDef[item].indicated" class="indicator"><i class="fas fa-circle"></i></span>
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime v-tooltip="$ts[navbarItemDef[item].title]" class="item _button" :class="item" active-class="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
<i class="fa-fw" :class="navbarItemDef[item].icon"></i>
<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="fas fa-circle"></i></span>
</component>
</template>
<div class="divider"></div>
@ -43,7 +43,7 @@ import { defineAsyncComponent, defineComponent } from 'vue';
import { host } from '@/config';
import { search } from '@/scripts/search';
import * as os from '@/os';
import { menuDef } from '@/menu';
import { navbarItemDef } from '@/navbar';
import { openAccountMenu } from '@/account';
import MkButton from '@/components/ui/button.vue';
@ -57,7 +57,7 @@ export default defineComponent({
host: host,
accounts: [],
connection: null,
menuDef: menuDef,
navbarItemDef: navbarItemDef,
settingsWindowed: false,
};
},
@ -68,9 +68,9 @@ export default defineComponent({
},
otherNavItemIndicated(): boolean {
for (const def in this.menuDef) {
for (const def in this.navbarItemDef) {
if (this.menu.includes(def)) continue;
if (this.menuDef[def].indicated) return true;
if (this.navbarItemDef[def].indicated) return true;
}
return false;
},
@ -113,7 +113,7 @@ export default defineComponent({
withExtraOperation: true,
}, ev);
},
}
},
});
</script>

View File

@ -14,9 +14,9 @@
</MkA>
<template v-for="item in menu">
<div v-if="item === '-'" class="divider"></div>
<component :is="menuDef[item].to ? 'MkA' : 'button'" v-else-if="menuDef[item] && (menuDef[item].show !== false)" v-click-anime class="item _button" :class="item" active-class="active" :to="menuDef[item].to" v-on="menuDef[item].action ? { click: menuDef[item].action } : {}">
<i class="fa-fw" :class="menuDef[item].icon"></i><span class="text">{{ $ts[menuDef[item].title] }}</span>
<span v-if="menuDef[item].indicated" class="indicator"><i class="fas fa-circle"></i></span>
<component :is="navbarItemDef[item].to ? 'MkA' : 'button'" v-else-if="navbarItemDef[item] && (navbarItemDef[item].show !== false)" v-click-anime class="item _button" :class="item" active-class="active" :to="navbarItemDef[item].to" v-on="navbarItemDef[item].action ? { click: navbarItemDef[item].action } : {}">
<i class="fa-fw" :class="navbarItemDef[item].icon"></i><span class="text">{{ $ts[navbarItemDef[item].title] }}</span>
<span v-if="navbarItemDef[item].indicated" class="indicator"><i class="fas fa-circle"></i></span>
</component>
</template>
<div class="divider"></div>
@ -45,7 +45,7 @@ import { defineAsyncComponent, defineComponent } from 'vue';
import { host } from '@/config';
import { search } from '@/scripts/search';
import * as os from '@/os';
import { menuDef } from '@/menu';
import { navbarItemDef } from '@/navbar';
import { openAccountMenu } from '@/account';
import MkButton from '@/components/ui/button.vue';
import { StickySidebar } from '@/scripts/sticky-sidebar';
@ -62,7 +62,7 @@ export default defineComponent({
host: host,
accounts: [],
connection: null,
menuDef: menuDef,
navbarItemDef: navbarItemDef,
iconOnly: false,
settingsWindowed: false,
};
@ -74,9 +74,9 @@ export default defineComponent({
},
otherNavItemIndicated(): boolean {
for (const def in this.menuDef) {
for (const def in this.navbarItemDef) {
if (this.menu.includes(def)) continue;
if (this.menuDef[def].indicated) return true;
if (this.navbarItemDef[def].indicated) return true;
}
return false;
},
@ -131,7 +131,7 @@ export default defineComponent({
withExtraOperation: true,
}, ev);
},
}
},
});
</script>

View File

@ -47,7 +47,6 @@ import XCommon from './_common_/common.vue';
import { instanceName } from '@/config';
import { StickySidebar } from '@/scripts/sticky-sidebar';
import * as os from '@/os';
import { menuDef } from '@/menu';
import { mainRouter } from '@/router';
import { PageMetadata, provideMetadataReceiver, setPageMetadata } from '@/scripts/page-metadata';
import { defaultStore } from '@/store';

View File

@ -69,12 +69,12 @@ import { v4 as uuid } from 'uuid';
import XCommon from './_common_/common.vue';
import { deckStore, addColumn as addColumnToStore, loadDeck } from './deck/deck-store';
import DeckColumnCore from '@/ui/deck/column-core.vue';
import XSidebar from '@/ui/_common_/sidebar.vue';
import XDrawerMenu from '@/ui/_common_/sidebar-for-mobile.vue';
import XSidebar from '@/ui/_common_/navbar.vue';
import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue';
import MkButton from '@/components/ui/button.vue';
import { getScrollContainer } from '@/scripts/scroll';
import * as os from '@/os';
import { menuDef } from '@/menu';
import { navbarItemDef } from '@/navbar';
import { $i } from '@/account';
import { i18n } from '@/i18n';
import { mainRouter } from '@/router';
@ -105,8 +105,8 @@ const columns = deckStore.reactiveState.columns;
const layout = deckStore.reactiveState.layout;
const menuIndicated = computed(() => {
if ($i == null) return false;
for (const def in menuDef) {
if (menuDef[def].indicated) return true;
for (const def in navbarItemDef) {
if (navbarItemDef[def].indicated) return true;
}
return false;
});

View File

@ -61,17 +61,17 @@ import { defineAsyncComponent, provide, onMounted, computed, ref, watch, Compute
import XCommon from './_common_/common.vue';
import { instanceName } from '@/config';
import { StickySidebar } from '@/scripts/sticky-sidebar';
import XDrawerMenu from '@/ui/_common_/sidebar-for-mobile.vue';
import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue';
import * as os from '@/os';
import { defaultStore } from '@/store';
import { menuDef } from '@/menu';
import { navbarItemDef } from '@/navbar';
import { i18n } from '@/i18n';
import { $i } from '@/account';
import { Router } from '@/nirax';
import { mainRouter } from '@/router';
import { PageMetadata, provideMetadataReceiver, setPageMetadata } from '@/scripts/page-metadata';
const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue'));
const XSidebar = defineAsyncComponent(() => import('@/ui/_common_/sidebar.vue'));
const XSidebar = defineAsyncComponent(() => import('@/ui/_common_/navbar.vue'));
const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
const DESKTOP_THRESHOLD = 1100;
@ -97,9 +97,9 @@ provideMetadataReceiver((info) => {
});
const menuIndicated = computed(() => {
for (const def in menuDef) {
for (const def in navbarItemDef) {
if (def === 'notifications') continue; //
if (menuDef[def].indicated) return true;
if (navbarItemDef[def].indicated) return true;
}
return false;
});

View File

@ -6,33 +6,33 @@ import { createFilter, dataToEsm } from '@rollup/pluginutils';
import { RollupJsonOptions } from '@rollup/plugin-json';
export default function json5(options: RollupJsonOptions = {}): Plugin {
const filter = createFilter(options.include, options.exclude);
const indent = 'indent' in options ? options.indent : '\t';
const filter = createFilter(options.include, options.exclude);
const indent = 'indent' in options ? options.indent : '\t';
return {
name: 'json5',
return {
name: 'json5',
// eslint-disable-next-line no-shadow
transform(json, id) {
if (id.slice(-6) !== '.json5' || !filter(id)) return null;
// eslint-disable-next-line no-shadow
transform(json, id) {
if (id.slice(-6) !== '.json5' || !filter(id)) return null;
try {
const parsed = JSON5.parse(json);
return {
code: dataToEsm(parsed, {
preferConst: options.preferConst,
compact: options.compact,
namedExports: options.namedExports,
indent
}),
map: { mappings: '' }
};
} catch (err) {
const message = 'Could not parse JSON file';
const position = parseInt(/[\d]/.exec(err.message)[0], 10);
this.warn({ message, id, position });
return null;
}
}
};
try {
const parsed = JSON5.parse(json);
return {
code: dataToEsm(parsed, {
preferConst: options.preferConst,
compact: options.compact,
namedExports: options.namedExports,
indent,
}),
map: { mappings: '' },
};
} catch (err) {
const message = 'Could not parse JSON file';
const position = parseInt(/[\d]/.exec(err.message)[0], 10);
this.warn({ message, id, position });
return null;
}
},
};
}