Merge branch 'develop' into pizzax-indexeddb
This commit is contained in:
@@ -170,10 +170,10 @@ export default defineComponent({
|
||||
aspectRatio: props.aspectRatio || 2.5,
|
||||
layout: {
|
||||
padding: {
|
||||
left: 16,
|
||||
right: 16,
|
||||
top: 16,
|
||||
bottom: 8,
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
|
@@ -1,65 +0,0 @@
|
||||
<template>
|
||||
<div v-size="{ max: [400] }" class="rbusrurv" :class="{ wide: forceWide }">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
forceWide: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rbusrurv {
|
||||
// 他のCSSからも参照されるので消さないように
|
||||
--debobigegoXPadding: 32px;
|
||||
--debobigegoYPadding: 32px;
|
||||
|
||||
--debobigegoContentHMargin: 16px;
|
||||
|
||||
font-size: 95%;
|
||||
line-height: 1.3em;
|
||||
background: var(--bg);
|
||||
padding: var(--debobigegoYPadding) var(--debobigegoXPadding);
|
||||
max-width: 750px;
|
||||
margin: 0 auto;
|
||||
|
||||
&:not(.wide).max-width_400px {
|
||||
--debobigegoXPadding: 0px;
|
||||
|
||||
> ::v-deep(*) {
|
||||
._debobigegoPanel {
|
||||
border: solid 0.5px var(--divider);
|
||||
border-radius: 0;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
._debobigego_group {
|
||||
> *:not(._debobigegoNoConcat) {
|
||||
&:not(:last-child):not(._debobigegoNoConcatPrev) {
|
||||
&._debobigegoPanel, ._debobigegoPanel {
|
||||
border-bottom: solid 0.5px var(--divider);
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-child):not(._debobigegoNoConcatNext) {
|
||||
&._debobigegoPanel, ._debobigegoPanel {
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,81 +0,0 @@
|
||||
<template>
|
||||
<div class="yzpgjkxe _debobigegoItem">
|
||||
<div class="_debobigegoLabel"><slot name="label"></slot></div>
|
||||
<button class="main _button _debobigegoPanel _debobigegoClickable" :class="{ center, primary, danger }">
|
||||
<slot></slot>
|
||||
<div class="suffix">
|
||||
<slot name="suffix"></slot>
|
||||
<div class="icon">
|
||||
<slot name="suffixIcon"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<div class="_debobigegoCaption"><slot name="desc"></slot></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import './debobigego.scss';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
primary: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
danger: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
center: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.yzpgjkxe {
|
||||
> .main {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 14px 16px;
|
||||
text-align: left;
|
||||
align-items: center;
|
||||
|
||||
&.center {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
color: #ff2a2a;
|
||||
}
|
||||
|
||||
> .suffix {
|
||||
display: inline-flex;
|
||||
margin-left: auto;
|
||||
opacity: 0.7;
|
||||
|
||||
> .icon {
|
||||
margin-left: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,52 +0,0 @@
|
||||
._debobigegoPanel {
|
||||
background: var(--panel);
|
||||
border-radius: var(--radius);
|
||||
transition: background 0.2s ease;
|
||||
|
||||
&._debobigegoClickable {
|
||||
&:hover {
|
||||
//background: var(--panelHighlight);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: var(--panelHighlight);
|
||||
transition: background 0s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
._debobigegoLabel,
|
||||
._debobigegoCaption {
|
||||
font-size: 80%;
|
||||
color: var(--fgTransparentWeak);
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
._debobigegoLabel {
|
||||
position: sticky;
|
||||
top: var(--stickyTop, 0px);
|
||||
z-index: 2;
|
||||
margin: -8px calc(var(--debobigegoXPadding) * -1) 0 calc(var(--debobigegoXPadding) * -1);
|
||||
padding: 8px calc(var(--debobigegoContentHMargin) + var(--debobigegoXPadding)) 8px calc(var(--debobigegoContentHMargin) + var(--debobigegoXPadding));
|
||||
background: var(--X17);
|
||||
-webkit-backdrop-filter: var(--blur, blur(10px));
|
||||
backdrop-filter: var(--blur, blur(10px));
|
||||
}
|
||||
|
||||
._themeChanging_ ._debobigegoLabel {
|
||||
transition: none !important;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
._debobigegoCaption {
|
||||
padding: 8px var(--debobigegoContentHMargin) 0 var(--debobigegoContentHMargin);
|
||||
}
|
||||
|
||||
._debobigegoItem {
|
||||
& + ._debobigegoItem {
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
@@ -1,78 +0,0 @@
|
||||
<template>
|
||||
<div v-size="{ max: [500] }" v-sticky-container class="vrtktovg _debobigegoItem _debobigegoNoConcat">
|
||||
<div class="_debobigegoLabel"><slot name="label"></slot></div>
|
||||
<div ref="child" class="main _debobigego_group">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="_debobigegoCaption"><slot name="caption"></slot></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, ref } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
setup(props, context) {
|
||||
const child = ref<HTMLElement | null>(null);
|
||||
|
||||
const scanChild = () => {
|
||||
if (child.value == null) return;
|
||||
const els = Array.from(child.value.children);
|
||||
for (let i = 0; i < els.length; i++) {
|
||||
const el = els[i];
|
||||
if (el.classList.contains('_debobigegoNoConcat')) {
|
||||
if (els[i - 1]) els[i - 1].classList.add('_debobigegoNoConcatPrev');
|
||||
if (els[i + 1]) els[i + 1].classList.add('_debobigegoNoConcatNext');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
scanChild();
|
||||
|
||||
const observer = new MutationObserver(records => {
|
||||
scanChild();
|
||||
});
|
||||
|
||||
observer.observe(child.value, {
|
||||
childList: true,
|
||||
subtree: false,
|
||||
attributes: false,
|
||||
characterData: false,
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
child
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.vrtktovg {
|
||||
> .main {
|
||||
> ::v-deep(*):not(._debobigegoNoConcat) {
|
||||
&:not(._debobigegoNoConcatNext) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:not(:last-child):not(._debobigegoNoConcatPrev) {
|
||||
&._debobigegoPanel, ._debobigegoPanel {
|
||||
border-bottom: solid 0.5px var(--divider);
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-child):not(._debobigegoNoConcatNext) {
|
||||
&._debobigegoPanel, ._debobigegoPanel {
|
||||
border-top: none;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<div class="fzenkabp _debobigegoItem">
|
||||
<div class="_debobigegoPanel" :class="{ warn }">
|
||||
<i v-if="warn" class="fas fa-exclamation-triangle"></i>
|
||||
<i v-else class="fas fa-info-circle"></i>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
warn: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.fzenkabp {
|
||||
> div {
|
||||
padding: 14px 16px;
|
||||
font-size: 90%;
|
||||
background: var(--infoBg);
|
||||
color: var(--infoFg);
|
||||
|
||||
&.warn {
|
||||
background: var(--infoWarnBg);
|
||||
color: var(--infoWarnFg);
|
||||
}
|
||||
|
||||
> i {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,292 +0,0 @@
|
||||
<template>
|
||||
<FormGroup class="_debobigegoItem">
|
||||
<template #label><slot></slot></template>
|
||||
<div class="ztzhwixg _debobigegoItem" :class="{ inline, disabled }">
|
||||
<div ref="icon" class="icon"><slot name="icon"></slot></div>
|
||||
<div class="input _debobigegoPanel">
|
||||
<div ref="prefixEl" class="prefix"><slot name="prefix"></slot></div>
|
||||
<input ref="inputEl"
|
||||
v-model="v"
|
||||
:type="type"
|
||||
:disabled="disabled"
|
||||
:required="required"
|
||||
:readonly="readonly"
|
||||
:placeholder="placeholder"
|
||||
:pattern="pattern"
|
||||
:autocomplete="autocomplete"
|
||||
:spellcheck="spellcheck"
|
||||
:step="step"
|
||||
:list="id"
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
@keydown="onKeydown($event)"
|
||||
@input="onInput"
|
||||
>
|
||||
<datalist v-if="datalist" :id="id">
|
||||
<option v-for="data in datalist" :value="data"/>
|
||||
</datalist>
|
||||
<div ref="suffixEl" class="suffix"><slot name="suffix"></slot></div>
|
||||
</div>
|
||||
</div>
|
||||
<template #caption><slot name="desc"></slot></template>
|
||||
|
||||
<FormButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormGroup>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs } from 'vue';
|
||||
import './debobigego.scss';
|
||||
import FormButton from './button.vue';
|
||||
import FormGroup from './group.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormGroup,
|
||||
FormButton,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
required: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
pattern: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
autofocus: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
autocomplete: {
|
||||
required: false
|
||||
},
|
||||
spellcheck: {
|
||||
required: false
|
||||
},
|
||||
step: {
|
||||
required: false
|
||||
},
|
||||
datalist: {
|
||||
type: Array,
|
||||
required: false,
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
manualSave: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
emits: ['change', 'keydown', 'enter', 'update:modelValue'],
|
||||
setup(props, context) {
|
||||
const { modelValue, type, autofocus } = toRefs(props);
|
||||
const v = ref(modelValue.value);
|
||||
const id = Math.random().toString(); // TODO: uuid?
|
||||
const focused = ref(false);
|
||||
const changed = ref(false);
|
||||
const invalid = ref(false);
|
||||
const filled = computed(() => v.value !== '' && v.value != null);
|
||||
const inputEl = ref(null);
|
||||
const prefixEl = ref(null);
|
||||
const suffixEl = ref(null);
|
||||
|
||||
const focus = () => inputEl.value.focus();
|
||||
const onInput = (ev) => {
|
||||
changed.value = true;
|
||||
context.emit('change', ev);
|
||||
};
|
||||
const onKeydown = (ev: KeyboardEvent) => {
|
||||
context.emit('keydown', ev);
|
||||
|
||||
if (ev.code === 'Enter') {
|
||||
context.emit('enter');
|
||||
}
|
||||
};
|
||||
|
||||
const updated = () => {
|
||||
changed.value = false;
|
||||
if (type?.value === 'number') {
|
||||
context.emit('update:modelValue', parseFloat(v.value));
|
||||
} else {
|
||||
context.emit('update:modelValue', v.value);
|
||||
}
|
||||
};
|
||||
|
||||
watch(modelValue.value, newValue => {
|
||||
v.value = newValue;
|
||||
});
|
||||
|
||||
watch(v, newValue => {
|
||||
if (!props.manualSave) {
|
||||
updated();
|
||||
}
|
||||
|
||||
invalid.value = inputEl.value.validity.badInput;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
if (autofocus.value) {
|
||||
focus();
|
||||
}
|
||||
|
||||
// このコンポーネントが作成された時、非表示状態である場合がある
|
||||
// 非表示状態だと要素の幅などは0になってしまうので、定期的に計算する
|
||||
const clock = setInterval(() => {
|
||||
if (prefixEl.value) {
|
||||
if (prefixEl.value.offsetWidth) {
|
||||
inputEl.value.style.paddingLeft = prefixEl.value.offsetWidth + 'px';
|
||||
}
|
||||
}
|
||||
if (suffixEl.value) {
|
||||
if (suffixEl.value.offsetWidth) {
|
||||
inputEl.value.style.paddingRight = suffixEl.value.offsetWidth + 'px';
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(clock);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
id,
|
||||
v,
|
||||
focused,
|
||||
invalid,
|
||||
changed,
|
||||
filled,
|
||||
inputEl,
|
||||
prefixEl,
|
||||
suffixEl,
|
||||
focus,
|
||||
onInput,
|
||||
onKeydown,
|
||||
updated,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ztzhwixg {
|
||||
position: relative;
|
||||
|
||||
> .icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
|
||||
&:not(:empty) + .input {
|
||||
margin-left: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
> .input {
|
||||
$height: 48px;
|
||||
position: relative;
|
||||
|
||||
> input {
|
||||
display: block;
|
||||
height: $height;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0 16px;
|
||||
font: inherit;
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
line-height: $height;
|
||||
color: var(--inputText);
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
box-sizing: border-box;
|
||||
|
||||
&[type='file'] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
> .prefix,
|
||||
> .suffix {
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
padding: 0 16px;
|
||||
font-size: 1em;
|
||||
line-height: $height;
|
||||
color: var(--inputLabel);
|
||||
pointer-events: none;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> * {
|
||||
display: inline-block;
|
||||
min-width: 16px;
|
||||
max-width: 150px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
> .prefix {
|
||||
left: 0;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
> .suffix {
|
||||
right: 0;
|
||||
padding-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.inline {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.7;
|
||||
|
||||
&, * {
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<div class="_debobigegoItem">
|
||||
<div class="_debobigegoPanel anocepby">
|
||||
<span class="key"><slot name="key"></slot></span>
|
||||
<span class="value"><slot name="value"></slot></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import './debobigego.scss';
|
||||
|
||||
export default defineComponent({
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.anocepby {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 14px var(--debobigegoContentHMargin);
|
||||
|
||||
> .key {
|
||||
margin-right: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
> .value {
|
||||
margin-left: auto;
|
||||
opacity: 0.7;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,103 +0,0 @@
|
||||
<template>
|
||||
<div class="qmfkfnzi _debobigegoItem">
|
||||
<a v-if="external" class="main _button _debobigegoPanel _debobigegoClickable" :href="to" target="_blank">
|
||||
<span class="icon"><slot name="icon"></slot></span>
|
||||
<span class="text"><slot></slot></span>
|
||||
<span class="right">
|
||||
<span class="text"><slot name="suffix"></slot></span>
|
||||
<i class="fas fa-external-link-alt icon"></i>
|
||||
</span>
|
||||
</a>
|
||||
<MkA v-else class="main _button _debobigegoPanel _debobigegoClickable" :class="{ active }" :to="to" :behavior="behavior">
|
||||
<span class="icon"><slot name="icon"></slot></span>
|
||||
<span class="text"><slot></slot></span>
|
||||
<span class="right">
|
||||
<span class="text"><slot name="suffix"></slot></span>
|
||||
<i class="fas fa-chevron-right icon"></i>
|
||||
</span>
|
||||
</MkA>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import './debobigego.scss';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
to: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
external: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
behavior: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.qmfkfnzi {
|
||||
> .main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 14px 16px 14px 14px;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--accent);
|
||||
background: var(--panelHighlight);
|
||||
}
|
||||
|
||||
> .icon {
|
||||
width: 32px;
|
||||
margin-right: 2px;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
opacity: 0.8;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
||||
& + .text {
|
||||
padding-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .text {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
> .right {
|
||||
margin-left: auto;
|
||||
opacity: 0.7;
|
||||
|
||||
> .text:not(:empty) {
|
||||
margin-right: 0.75em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,102 +0,0 @@
|
||||
<template>
|
||||
<FormGroup class="_debobigegoItem">
|
||||
<template #label><slot></slot></template>
|
||||
<div class="drooglns _debobigegoItem" :class="{ tall }">
|
||||
<div class="input _debobigegoPanel">
|
||||
<textarea v-model="v"
|
||||
class="_monospace"
|
||||
readonly
|
||||
:spellcheck="false"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<template #caption><slot name="desc"></slot></template>
|
||||
</FormGroup>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, toRefs, watch } from 'vue';
|
||||
import * as JSON5 from 'json5';
|
||||
import './debobigego.scss';
|
||||
import FormGroup from './group.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormGroup,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
required: false
|
||||
},
|
||||
tall: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
pre: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
manualSave: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
const { value } = toRefs(props);
|
||||
const v = ref('');
|
||||
|
||||
watch(() => value, newValue => {
|
||||
v.value = JSON5.stringify(newValue.value, null, '\t');
|
||||
}, {
|
||||
immediate: true
|
||||
});
|
||||
|
||||
return {
|
||||
v,
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.drooglns {
|
||||
position: relative;
|
||||
|
||||
> .input {
|
||||
position: relative;
|
||||
|
||||
> textarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
min-height: 130px;
|
||||
margin: 0;
|
||||
padding: 16px var(--debobigegoContentHMargin);
|
||||
box-sizing: border-box;
|
||||
font: inherit;
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
color: var(--fg);
|
||||
tab-size: 2;
|
||||
white-space: pre;
|
||||
}
|
||||
}
|
||||
|
||||
&.tall {
|
||||
> .input {
|
||||
> textarea {
|
||||
min-height: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,42 +0,0 @@
|
||||
<template>
|
||||
<FormGroup class="uljviswt _debobigegoItem">
|
||||
<template #label><slot name="label"></slot></template>
|
||||
<slot :items="items"></slot>
|
||||
<div v-if="empty" key="_empty_" class="empty">
|
||||
<slot name="empty"></slot>
|
||||
</div>
|
||||
<FormButton v-show="more" class="button" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" primary @click="fetchMore">
|
||||
<template v-if="!moreFetching">{{ $ts.loadMore }}</template>
|
||||
<template v-if="moreFetching"><MkLoading inline/></template>
|
||||
</FormButton>
|
||||
</FormGroup>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormButton from './button.vue';
|
||||
import FormGroup from './group.vue';
|
||||
import paging from '@/scripts/paging';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormButton,
|
||||
FormGroup,
|
||||
},
|
||||
|
||||
mixins: [
|
||||
paging({}),
|
||||
],
|
||||
|
||||
props: {
|
||||
pagination: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uljviswt {
|
||||
}
|
||||
</style>
|
@@ -1,112 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent, h } from 'vue';
|
||||
import MkRadio from '@/components/form/radio.vue';
|
||||
import './debobigego.scss';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MkRadio
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
required: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: this.modelValue,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
modelValue() {
|
||||
this.value = this.modelValue;
|
||||
},
|
||||
value() {
|
||||
this.$emit('update:modelValue', this.value);
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const label = this.$slots.desc();
|
||||
let options = this.$slots.default();
|
||||
|
||||
// なぜかFragmentになることがあるため
|
||||
if (options.length === 1 && options[0].props == null) options = options[0].children;
|
||||
|
||||
return h('div', {
|
||||
class: 'cnklmpwm _debobigegoItem'
|
||||
}, [
|
||||
h('div', {
|
||||
class: '_debobigegoLabel',
|
||||
}, label),
|
||||
...options.map(option => h('button', {
|
||||
class: '_button _debobigegoPanel _debobigegoClickable',
|
||||
key: option.key,
|
||||
onClick: () => this.value = option.props.value,
|
||||
}, [h('span', {
|
||||
class: ['check', { checked: this.value === option.props.value }],
|
||||
}), option.children]))
|
||||
]);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.cnklmpwm {
|
||||
> button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 14px 18px;
|
||||
text-align: left;
|
||||
|
||||
&:not(:first-of-type) {
|
||||
border-top: none !important;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: solid 0.5px var(--divider);
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
> .check {
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 8px;
|
||||
background: none;
|
||||
border: 2px solid var(--inputBorder);
|
||||
border-radius: 100%;
|
||||
transition: inherit;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
bottom: 3px;
|
||||
left: 3px;
|
||||
border-radius: 100%;
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
transition: .4s cubic-bezier(.25,.8,.25,1);
|
||||
}
|
||||
|
||||
&.checked {
|
||||
border-color: var(--accent);
|
||||
|
||||
&:after {
|
||||
background-color: var(--accent);
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,122 +0,0 @@
|
||||
<template>
|
||||
<div class="ifitouly _debobigegoItem" :class="{ focused, disabled }">
|
||||
<div class="_debobigegoLabel"><slot name="label"></slot></div>
|
||||
<div class="_debobigegoPanel main">
|
||||
<input
|
||||
ref="input"
|
||||
v-model="v"
|
||||
type="range"
|
||||
:disabled="disabled"
|
||||
:min="min"
|
||||
:max="max"
|
||||
:step="step"
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
@input="$emit('update:value', $event.target.value)"
|
||||
/>
|
||||
</div>
|
||||
<div class="_debobigegoCaption"><slot name="caption"></slot></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 100
|
||||
},
|
||||
step: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 1
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
v: this.value,
|
||||
focused: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(v) {
|
||||
this.v = parseFloat(v);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ifitouly {
|
||||
position: relative;
|
||||
|
||||
> .main {
|
||||
padding: 22px 16px;
|
||||
|
||||
> input {
|
||||
display: block;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background: var(--X10);
|
||||
height: 4px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
border-radius: 7px;
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
background: var(--accent);
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
background: var(--accent);
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<div class="yrtfrpux _debobigegoItem" :class="{ disabled, inline }">
|
||||
<div class="_debobigegoLabel"><slot name="label"></slot></div>
|
||||
<div ref="icon" class="icon"><slot name="icon"></slot></div>
|
||||
<div class="input _debobigegoPanel _debobigegoClickable" @click="focus">
|
||||
<div ref="prefix" class="prefix"><slot name="prefix"></slot></div>
|
||||
<select ref="input"
|
||||
v-model="v"
|
||||
:required="required"
|
||||
:disabled="disabled"
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
>
|
||||
<slot></slot>
|
||||
</select>
|
||||
<div class="suffix">
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_debobigegoCaption"><slot name="caption"></slot></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import './debobigego.scss';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
modelValue: {
|
||||
required: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
v: {
|
||||
get() {
|
||||
return this.modelValue;
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('update:modelValue', v);
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
focus() {
|
||||
this.$refs.input.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.yrtfrpux {
|
||||
position: relative;
|
||||
|
||||
> .icon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
line-height: 32px;
|
||||
|
||||
&:not(:empty) + .input {
|
||||
margin-left: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
> .input {
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
> select {
|
||||
display: block;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
padding: 0 16px;
|
||||
font: inherit;
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
height: 48px;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
color: var(--fg);
|
||||
|
||||
option,
|
||||
optgroup {
|
||||
color: var(--fg);
|
||||
background: var(--bg);
|
||||
}
|
||||
}
|
||||
|
||||
> .prefix,
|
||||
> .suffix {
|
||||
display: block;
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
font-size: 1em;
|
||||
line-height: 32px;
|
||||
color: var(--inputLabel);
|
||||
pointer-events: none;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> * {
|
||||
display: block;
|
||||
min-width: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
> .prefix {
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
> .suffix {
|
||||
padding: 0 16px 0 0;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,101 +0,0 @@
|
||||
<template>
|
||||
<transition name="fade" mode="out-in">
|
||||
<div v-if="pending" class="_debobigegoItem">
|
||||
<div class="_debobigegoPanel">
|
||||
<MkLoading/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="resolved" class="_debobigegoItem">
|
||||
<slot :result="result"></slot>
|
||||
</div>
|
||||
<div v-else class="_debobigegoItem">
|
||||
<div class="_debobigegoPanel eiurkvay">
|
||||
<div><i class="fas fa-exclamation-triangle"></i> {{ $ts.somethingHappened }}</div>
|
||||
<MkButton inline class="retry" @click="retry"><i class="fas fa-redo-alt"></i> {{ $ts.retry }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType, ref, watch } from 'vue';
|
||||
import './debobigego.scss';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MkButton
|
||||
},
|
||||
|
||||
props: {
|
||||
p: {
|
||||
type: Function as PropType<() => Promise<any>>,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
|
||||
setup(props, context) {
|
||||
const pending = ref(true);
|
||||
const resolved = ref(false);
|
||||
const rejected = ref(false);
|
||||
const result = ref(null);
|
||||
|
||||
const process = () => {
|
||||
if (props.p == null) {
|
||||
return;
|
||||
}
|
||||
const promise = props.p();
|
||||
pending.value = true;
|
||||
resolved.value = false;
|
||||
rejected.value = false;
|
||||
promise.then((_result) => {
|
||||
pending.value = false;
|
||||
resolved.value = true;
|
||||
result.value = _result;
|
||||
});
|
||||
promise.catch(() => {
|
||||
pending.value = false;
|
||||
rejected.value = true;
|
||||
});
|
||||
};
|
||||
|
||||
watch(() => props.p, () => {
|
||||
process();
|
||||
}, {
|
||||
immediate: true
|
||||
});
|
||||
|
||||
const retry = () => {
|
||||
process();
|
||||
};
|
||||
|
||||
return {
|
||||
pending,
|
||||
resolved,
|
||||
rejected,
|
||||
result,
|
||||
retry,
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.125s ease;
|
||||
}
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.eiurkvay {
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
|
||||
> .retry {
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,132 +0,0 @@
|
||||
<template>
|
||||
<div class="ijnpvmgr _debobigegoItem">
|
||||
<div class="main _debobigegoPanel _debobigegoClickable"
|
||||
:class="{ disabled, checked }"
|
||||
:aria-checked="checked"
|
||||
:aria-disabled="disabled"
|
||||
@click.prevent="toggle"
|
||||
>
|
||||
<input
|
||||
ref="input"
|
||||
type="checkbox"
|
||||
:disabled="disabled"
|
||||
@keydown.enter="toggle"
|
||||
>
|
||||
<span v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button">
|
||||
<span class="handle"></span>
|
||||
</span>
|
||||
<span class="label">
|
||||
<span><slot></slot></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="_debobigegoCaption"><slot name="desc"></slot></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import './debobigego.scss';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
checked(): boolean {
|
||||
return this.modelValue;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggle() {
|
||||
if (this.disabled) return;
|
||||
this.$emit('update:modelValue', !this.checked);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.ijnpvmgr {
|
||||
> .main {
|
||||
position: relative;
|
||||
display: flex;
|
||||
padding: 14px 16px;
|
||||
cursor: pointer;
|
||||
|
||||
> * {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
> input {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> .button {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
margin: 0;
|
||||
width: 34px;
|
||||
height: 22px;
|
||||
background: var(--switchBg);
|
||||
outline: none;
|
||||
border-radius: 999px;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
|
||||
> .handle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 3px;
|
||||
bottom: 0;
|
||||
margin: auto 0;
|
||||
border-radius: 100%;
|
||||
transition: background-color 0.3s, transform 0.3s;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #fff;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
> .label {
|
||||
margin-left: 12px;
|
||||
display: block;
|
||||
transition: inherit;
|
||||
color: var(--fg);
|
||||
|
||||
> span {
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
transition: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.checked {
|
||||
> .button {
|
||||
background-color: var(--accent);
|
||||
|
||||
> .handle {
|
||||
transform: translateX(12px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,161 +0,0 @@
|
||||
<template>
|
||||
<FormGroup class="_debobigegoItem">
|
||||
<template #label><slot></slot></template>
|
||||
<div class="rivhosbp _debobigegoItem" :class="{ tall, pre }">
|
||||
<div class="input _debobigegoPanel">
|
||||
<textarea ref="input" v-model="v"
|
||||
:class="{ code, _monospace: code }"
|
||||
:required="required"
|
||||
:readonly="readonly"
|
||||
:pattern="pattern"
|
||||
:autocomplete="autocomplete"
|
||||
:spellcheck="!code"
|
||||
@input="onInput"
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<template #caption><slot name="desc"></slot></template>
|
||||
|
||||
<FormButton v-if="manualSave && changed" primary @click="updated"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormGroup>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, toRefs, watch } from 'vue';
|
||||
import './debobigego.scss';
|
||||
import FormButton from './button.vue';
|
||||
import FormGroup from './group.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormGroup,
|
||||
FormButton,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
required: false
|
||||
},
|
||||
required: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
pattern: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
autocomplete: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
code: {
|
||||
type: Boolean,
|
||||
required: false
|
||||
},
|
||||
tall: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
pre: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
manualSave: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
const { modelValue } = toRefs(props);
|
||||
const v = ref(modelValue.value);
|
||||
const changed = ref(false);
|
||||
const inputEl = ref(null);
|
||||
const focus = () => inputEl.value.focus();
|
||||
const onInput = (ev) => {
|
||||
changed.value = true;
|
||||
context.emit('change', ev);
|
||||
};
|
||||
|
||||
const updated = () => {
|
||||
changed.value = false;
|
||||
context.emit('update:modelValue', v.value);
|
||||
};
|
||||
|
||||
watch(modelValue.value, newValue => {
|
||||
v.value = newValue;
|
||||
});
|
||||
|
||||
watch(v, newValue => {
|
||||
if (!props.manualSave) {
|
||||
updated();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
v,
|
||||
updated,
|
||||
changed,
|
||||
focus,
|
||||
onInput,
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rivhosbp {
|
||||
position: relative;
|
||||
|
||||
> .input {
|
||||
position: relative;
|
||||
|
||||
> textarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
min-height: 130px;
|
||||
margin: 0;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
font: inherit;
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
color: var(--fg);
|
||||
|
||||
&.code {
|
||||
tab-size: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.tall {
|
||||
> .input {
|
||||
> textarea {
|
||||
min-height: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.pre {
|
||||
> .input {
|
||||
> textarea {
|
||||
white-space: pre;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,36 +0,0 @@
|
||||
<template>
|
||||
<div v-size="{ max: [500] }" class="wthhikgt _debobigegoItem">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wthhikgt {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
> ::v-deep(*) {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.max-width_500px {
|
||||
display: block;
|
||||
|
||||
> ::v-deep(*) {
|
||||
margin: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
107
packages/client/src/components/form/folder.vue
Normal file
107
packages/client/src/components/form/folder.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<div class="dwzlatin" :class="{ opened }">
|
||||
<div class="header _button" @click="toggle">
|
||||
<span class="icon"><slot name="icon"></slot></span>
|
||||
<span class="text"><slot name="label"></slot></span>
|
||||
<span class="right">
|
||||
<span class="text"><slot name="suffix"></slot></span>
|
||||
<i v-if="opened" class="fas fa-angle-up icon"></i>
|
||||
<i v-else class="fas fa-angle-down icon"></i>
|
||||
</span>
|
||||
</div>
|
||||
<keep-alive>
|
||||
<div v-if="openedAtLeastOnce" v-show="opened" class="body">
|
||||
<MkSpacer :margin-min="14" :margin-max="22">
|
||||
<slot></slot>
|
||||
</MkSpacer>
|
||||
</div>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const props = withDefaults(defineProps<{
|
||||
defaultOpen: boolean;
|
||||
}>(), {
|
||||
defaultOpen: false,
|
||||
})
|
||||
|
||||
let opened = $ref(props.defaultOpen);
|
||||
let openedAtLeastOnce = $ref(props.defaultOpen);
|
||||
|
||||
const toggle = () => {
|
||||
opened = !opened;
|
||||
if (opened) {
|
||||
openedAtLeastOnce = true;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dwzlatin {
|
||||
display: block;
|
||||
|
||||
> .header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 12px 14px 12px 14px;
|
||||
background: var(--buttonBg);
|
||||
border-radius: 6px;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
background: var(--buttonHoverBg);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--accent);
|
||||
background: var(--buttonHoverBg);
|
||||
}
|
||||
|
||||
> .icon {
|
||||
margin-right: 0.75em;
|
||||
flex-shrink: 0;
|
||||
text-align: center;
|
||||
opacity: 0.8;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
|
||||
& + .text {
|
||||
padding-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .text {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
> .right {
|
||||
margin-left: auto;
|
||||
opacity: 0.7;
|
||||
white-space: nowrap;
|
||||
|
||||
> .text:not(:empty) {
|
||||
margin-right: 0.75em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .body {
|
||||
background: var(--panel);
|
||||
border-radius: 0 0 6px 6px;
|
||||
}
|
||||
|
||||
&.opened {
|
||||
> .header {
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-sticky-container v-panel class="adfeebaf _formBlock">
|
||||
<div v-sticky-container class="adfeebaf _formBlock">
|
||||
<div class="label"><slot name="label"></slot></div>
|
||||
<div class="main _formRoot">
|
||||
<slot></slot>
|
||||
@@ -17,6 +17,7 @@ export default defineComponent({
|
||||
<style lang="scss" scoped>
|
||||
.adfeebaf {
|
||||
padding: 24px 24px;
|
||||
border: solid 1px var(--divider);
|
||||
border-radius: var(--radius);
|
||||
|
||||
> .label {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
v-panel
|
||||
v-adaptive-border
|
||||
class="novjtctn"
|
||||
:class="{ disabled, checked }"
|
||||
:aria-checked="checked"
|
||||
@@ -53,7 +53,10 @@ export default defineComponent({
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
padding: 11px 14px;
|
||||
padding: 10px 12px;
|
||||
background-color: var(--panel);
|
||||
background-clip: padding-box !important;
|
||||
border: solid 1px var(--panel);
|
||||
border-radius: 6px;
|
||||
transition: all 0.3s;
|
||||
|
||||
@@ -69,9 +72,13 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: var(--inputBorderHover) !important;
|
||||
}
|
||||
|
||||
&.checked {
|
||||
background: var(--accentedBg) !important;
|
||||
border-color: var(--accent);
|
||||
background-color: var(--accentedBg) !important;
|
||||
border-color: var(--accentedBg) !important;
|
||||
color: var(--accent);
|
||||
|
||||
&, * {
|
||||
@@ -89,11 +96,6 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: var(--inputBorderHover);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
> input {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-size="{ max: [500] }" v-sticky-container class="vrtktovh _formBlock">
|
||||
<div class="vrtktovh _formBlock">
|
||||
<div class="label"><slot name="label"></slot></div>
|
||||
<div class="main _formRoot">
|
||||
<slot></slot>
|
||||
@@ -12,10 +12,8 @@
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.vrtktovh {
|
||||
margin: 0;
|
||||
border-top: solid 0.5px var(--divider);
|
||||
border-bottom: solid 0.5px var(--divider);
|
||||
padding: 24px 0;
|
||||
|
||||
& + .vrtktovh {
|
||||
border-top: none;
|
||||
@@ -31,7 +29,7 @@
|
||||
|
||||
> .label {
|
||||
font-weight: bold;
|
||||
padding: 0 0 16px 0;
|
||||
margin: 1.5em 0 16px 0;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
@@ -39,6 +37,7 @@
|
||||
}
|
||||
|
||||
> .main {
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -111,7 +111,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
> .label {
|
||||
margin-left: 16px;
|
||||
margin-left: 12px;
|
||||
margin-top: 2px;
|
||||
display: block;
|
||||
transition: inherit;
|
||||
|
@@ -40,7 +40,7 @@ export default defineComponent({
|
||||
return;
|
||||
}
|
||||
|
||||
if (rect.width > props.contentMax || rect.width > 500) {
|
||||
if (rect.width > props.contentMax || (rect.width > 360 && window.innerWidth > 400)) {
|
||||
margin.value = props.marginMax;
|
||||
} else {
|
||||
margin.value = props.marginMin;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="zbcjwnqg" style="margin-top: -8px;">
|
||||
<div class="zbcjwnqg">
|
||||
<div class="selects" style="display: flex;">
|
||||
<MkSelect v-model="chartSrc" style="margin: 0; flex: 1;">
|
||||
<optgroup :label="$ts.federation">
|
||||
@@ -29,16 +29,16 @@
|
||||
<option value="day">{{ $ts.perDay }}</option>
|
||||
</MkSelect>
|
||||
</div>
|
||||
<MkChart :src="chartSrc" :span="chartSpan" :limit="chartLimit" :detailed="detailed"></MkChart>
|
||||
<div class="chart">
|
||||
<MkChart :src="chartSrc" :span="chartSpan" :limit="chartLimit" :detailed="detailed"></MkChart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, ref, watch } from 'vue';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import MkSelect from '@/components/form/select.vue';
|
||||
import MkChart from '@/components/chart.vue';
|
||||
import * as os from '@/os';
|
||||
import { defaultStore } from '@/store';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -74,7 +74,10 @@ export default defineComponent({
|
||||
<style lang="scss" scoped>
|
||||
.zbcjwnqg {
|
||||
> .selects {
|
||||
padding: 8px 16px 0 16px;
|
||||
}
|
||||
|
||||
> .chart {
|
||||
padding: 8px 0 0 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="alqyeyti">
|
||||
<div class="alqyeyti" :class="{ oneline }">
|
||||
<div class="key">
|
||||
<slot name="key"></slot>
|
||||
</div>
|
||||
@@ -22,6 +22,11 @@ export default defineComponent({
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
oneline: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
@@ -39,10 +44,30 @@ export default defineComponent({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.alqyeyti {
|
||||
> .key, > .value {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
> .key {
|
||||
font-size: 0.85em;
|
||||
padding: 0 0 0.25em 0;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
&.oneline {
|
||||
display: flex;
|
||||
|
||||
> .key {
|
||||
width: 30%;
|
||||
font-size: 1em;
|
||||
padding: 0 8px 0 0;
|
||||
}
|
||||
|
||||
> .value {
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
108
packages/client/src/components/object-view.value.vue
Normal file
108
packages/client/src/components/object-view.value.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div class="igpposuu _monospace">
|
||||
<div v-if="value === null" class="null">null</div>
|
||||
<div v-else-if="typeof value === 'boolean'" class="boolean">{{ value ? 'true' : 'false' }}</div>
|
||||
<div v-else-if="typeof value === 'string'" class="string">"{{ value }}"</div>
|
||||
<div v-else-if="typeof value === 'number'" class="number">{{ number(value) }}</div>
|
||||
<div v-else-if="Array.isArray(value)" class="array">
|
||||
<button @click="collapsed_ = !collapsed_">[ {{ collapsed_ ? '+' : '-' }} ]</button>
|
||||
<template v-if="!collapsed_">
|
||||
<div v-for="i in value.length" class="element">
|
||||
{{ i }}: <XValue :value="value[i - 1]" collapsed/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else-if="typeof value === 'object'" class="object">
|
||||
<button @click="collapsed_ = !collapsed_">{ {{ collapsed_ ? '+' : '-' }} }</button>
|
||||
<template v-if="!collapsed_">
|
||||
<div v-for="k in Object.keys(value)" class="kv">
|
||||
<div class="k">{{ k }}:</div>
|
||||
<div class="v"><XValue :value="value[k]" collapsed/></div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, ref } from 'vue';
|
||||
import number from '@/filters/number';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'XValue',
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
const collapsed_ = ref(props.collapsed);
|
||||
|
||||
return {
|
||||
number,
|
||||
collapsed_,
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.igpposuu {
|
||||
display: inline;
|
||||
|
||||
> .null {
|
||||
display: inline;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
> .boolean {
|
||||
display: inline;
|
||||
color: var(--codeBoolean);
|
||||
}
|
||||
|
||||
> .string {
|
||||
display: inline;
|
||||
color: var(--codeString);
|
||||
}
|
||||
|
||||
> .number {
|
||||
display: inline;
|
||||
color: var(--codeNumber);
|
||||
}
|
||||
|
||||
> .array {
|
||||
display: inline;
|
||||
|
||||
> .element {
|
||||
display: block;
|
||||
padding-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
> .object {
|
||||
display: inline;
|
||||
|
||||
> .kv {
|
||||
display: block;
|
||||
padding-left: 16px;
|
||||
|
||||
> .k {
|
||||
display: inline;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
> .v {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
33
packages/client/src/components/object-view.vue
Normal file
33
packages/client/src/components/object-view.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="zhyxdalp">
|
||||
<XValue :value="value" :collapsed="false"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import XValue from './object-view.value.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XValue
|
||||
},
|
||||
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.zhyxdalp {
|
||||
|
||||
}
|
||||
</style>
|
@@ -13,8 +13,6 @@ if (localStorage.getItem('accounts') != null) {
|
||||
}
|
||||
//#endregion
|
||||
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { Integrations } from '@sentry/tracing';
|
||||
import { computed, createApp, watch, markRaw, version as vueVersion } from 'vue';
|
||||
import * as compareVersions from 'compare-versions';
|
||||
|
||||
@@ -77,18 +75,6 @@ if (_DEV_) {
|
||||
});
|
||||
}
|
||||
|
||||
if (defaultStore.state.reportError && !_DEV_) {
|
||||
Sentry.init({
|
||||
dsn: 'https://fd273254a07a4b61857607a9ea05d629@o501808.ingest.sentry.io/5583438',
|
||||
tracesSampleRate: 1.0,
|
||||
});
|
||||
|
||||
Sentry.setTag('misskey_version', version);
|
||||
Sentry.setTag('ui', ui);
|
||||
Sentry.setTag('lang', lang);
|
||||
Sentry.setTag('host', host);
|
||||
}
|
||||
|
||||
// タッチデバイスでCSSの:hoverを機能させる
|
||||
document.addEventListener('touchend', () => {}, { passive: true });
|
||||
|
||||
|
@@ -4,7 +4,6 @@ import { Component, defineAsyncComponent, markRaw, reactive, Ref, ref } from 'vu
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import insertTextAtCursor from 'insert-text-at-cursor';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { apiUrl, debug, url } from '@/config';
|
||||
import MkPostFormDialog from '@/components/post-form-dialog.vue';
|
||||
import MkWaitingDialog from '@/components/waiting-dialog.vue';
|
||||
@@ -70,19 +69,6 @@ export const api = ((endpoint: string, data: Record<string, any> = {}, token?: s
|
||||
log!.res = markRaw(body.error);
|
||||
log!.state = 'failed';
|
||||
}
|
||||
|
||||
if (defaultStore.state.reportError && !_DEV_) {
|
||||
Sentry.withScope((scope) => {
|
||||
scope.setTag('api_endpoint', endpoint);
|
||||
scope.setContext('api params', data);
|
||||
scope.setContext('api error info', body.info);
|
||||
scope.setTag('api_error_id', body.id);
|
||||
scope.setTag('api_error_code', body.code);
|
||||
scope.setTag('api_error_kind', body.kind);
|
||||
scope.setLevel(Sentry.Severity.Error);
|
||||
Sentry.captureMessage('API error');
|
||||
});
|
||||
}
|
||||
}
|
||||
}).catch(reject);
|
||||
});
|
||||
|
@@ -93,7 +93,8 @@ export default defineComponent({
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.instanceInfo,
|
||||
icon: 'fas fa-info-circle'
|
||||
icon: 'fas fa-info-circle',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
host,
|
||||
version,
|
||||
|
@@ -1,70 +1,55 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<div>
|
||||
<FormSuspense :p="init">
|
||||
<FormRadios v-model="provider">
|
||||
<template #desc><i class="fas fa-shield-alt"></i> {{ $ts.botProtection }}</template>
|
||||
<option :value="null">{{ $ts.none }} ({{ $ts.notRecommended }})</option>
|
||||
<option value="hcaptcha">hCaptcha</option>
|
||||
<option value="recaptcha">reCAPTCHA</option>
|
||||
</FormRadios>
|
||||
<div class="_formRoot">
|
||||
<FormRadios v-model="provider" class="_formBlock">
|
||||
<option :value="null">{{ $ts.none }} ({{ $ts.notRecommended }})</option>
|
||||
<option value="hcaptcha">hCaptcha</option>
|
||||
<option value="recaptcha">reCAPTCHA</option>
|
||||
</FormRadios>
|
||||
|
||||
<template v-if="provider === 'hcaptcha'">
|
||||
<div v-sticky-container class="_debobigegoItem _debobigegoNoConcat">
|
||||
<div class="_debobigegoLabel">hCaptcha</div>
|
||||
<div class="main">
|
||||
<FormInput v-model="hcaptchaSiteKey">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
<span>{{ $ts.hcaptchaSiteKey }}</span>
|
||||
</FormInput>
|
||||
<FormInput v-model="hcaptchaSecretKey">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
<span>{{ $ts.hcaptchaSecretKey }}</span>
|
||||
</FormInput>
|
||||
</div>
|
||||
</div>
|
||||
<div v-sticky-container class="_debobigegoItem _debobigegoNoConcat">
|
||||
<div class="_debobigegoLabel">{{ $ts.preview }}</div>
|
||||
<div class="_debobigegoPanel" style="padding: var(--debobigegoContentHMargin);">
|
||||
<template v-if="provider === 'hcaptcha'">
|
||||
<FormInput v-model="hcaptchaSiteKey" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
<template #label>{{ $ts.hcaptchaSiteKey }}</template>
|
||||
</FormInput>
|
||||
<FormInput v-model="hcaptchaSecretKey" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
<template #label>{{ $ts.hcaptchaSecretKey }}</template>
|
||||
</FormInput>
|
||||
<FormSlot class="_formBlock">
|
||||
<template #label>{{ $ts.preview }}</template>
|
||||
<MkCaptcha provider="hcaptcha" :sitekey="hcaptchaSiteKey || '10000000-ffff-ffff-ffff-000000000001'"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="provider === 'recaptcha'">
|
||||
<div v-sticky-container class="_debobigegoItem _debobigegoNoConcat">
|
||||
<div class="_debobigegoLabel">reCAPTCHA</div>
|
||||
<div class="main">
|
||||
<FormInput v-model="recaptchaSiteKey">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
<span>{{ $ts.recaptchaSiteKey }}</span>
|
||||
</FormInput>
|
||||
<FormInput v-model="recaptchaSecretKey">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
<span>{{ $ts.recaptchaSecretKey }}</span>
|
||||
</FormInput>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="recaptchaSiteKey" v-sticky-container class="_debobigegoItem _debobigegoNoConcat">
|
||||
<div class="_debobigegoLabel">{{ $ts.preview }}</div>
|
||||
<div class="_debobigegoPanel" style="padding: var(--debobigegoContentHMargin);">
|
||||
</FormSlot>
|
||||
</template>
|
||||
<template v-else-if="provider === 'recaptcha'">
|
||||
<FormInput v-model="recaptchaSiteKey" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
<template #label>{{ $ts.recaptchaSiteKey }}</template>
|
||||
</FormInput>
|
||||
<FormInput v-model="recaptchaSecretKey" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
<template #label>{{ $ts.recaptchaSecretKey }}</template>
|
||||
</FormInput>
|
||||
<FormSlot v-if="recaptchaSiteKey" class="_formBlock">
|
||||
<template #label>{{ $ts.preview }}</template>
|
||||
<MkCaptcha provider="recaptcha" :sitekey="recaptchaSiteKey"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</FormSlot>
|
||||
</template>
|
||||
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormRadios from '@/components/debobigego/radios.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormRadios from '@/components/form/radios.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import FormSlot from '@/components/form/slot.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
@@ -73,11 +58,9 @@ export default defineComponent({
|
||||
components: {
|
||||
FormRadios,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormButton,
|
||||
FormInfo,
|
||||
FormSuspense,
|
||||
FormSlot,
|
||||
MkCaptcha: defineAsyncComponent(() => import('@/components/captcha.vue')),
|
||||
},
|
||||
|
||||
|
@@ -1,28 +1,18 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<MkSpacer :content-max="800" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense v-slot="{ result: database }" :p="databasePromiseFactory">
|
||||
<FormGroup v-for="table in database" :key="table[0]">
|
||||
<template #label>{{ table[0] }}</template>
|
||||
<FormKeyValueView>
|
||||
<template #key>Size</template>
|
||||
<template #value>{{ bytes(table[1].size) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>Records</template>
|
||||
<template #value>{{ number(table[1].count) }}</template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<MkKeyValue v-for="table in database" :key="table[0]" oneline style="margin: 1em 0;">
|
||||
<template #key>{{ table[0] }}</template>
|
||||
<template #value>{{ bytes(table[1].size) }} ({{ number(table[1].count) }} recs)</template>
|
||||
</MkKeyValue>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import MkKeyValue from '@/components/key-value.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import bytes from '@/filters/bytes';
|
||||
@@ -31,10 +21,7 @@ import number from '@/filters/number';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormSuspense,
|
||||
FormKeyValueView,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormLink,
|
||||
MkKeyValue,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
@@ -10,7 +10,7 @@
|
||||
</div>
|
||||
|
||||
<MkInfo v-if="noMaintainerInformation" warn class="info">{{ $ts.noMaintainerInformationWarning }} <MkA to="/admin/settings" class="_link">{{ $ts.configure }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noBotProtection" warn class="info">{{ $ts.noBotProtectionWarning }} <MkA to="/admin/bot-protection" class="_link">{{ $ts.configure }}</MkA></MkInfo>
|
||||
<MkInfo v-if="noBotProtection" warn class="info">{{ $ts.noBotProtectionWarning }} <MkA to="/admin/security" class="_link">{{ $ts.configure }}</MkA></MkInfo>
|
||||
|
||||
<MkSuperMenu :def="menuDef" :grid="page == null"></MkSuperMenu>
|
||||
</div>
|
||||
@@ -29,9 +29,6 @@
|
||||
import { computed, defineAsyncComponent, defineComponent, isRef, nextTick, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { i18n } from '@/i18n';
|
||||
import MkSuperMenu from '@/components/ui/super-menu.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import MkInfo from '@/components/ui/info.vue';
|
||||
import { scroll } from '@/scripts/scroll';
|
||||
import { instance } from '@/instance';
|
||||
@@ -41,10 +38,7 @@ import { lookupUser } from '@/scripts/lookup-user';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
MkSuperMenu,
|
||||
FormGroup,
|
||||
FormButton,
|
||||
MkInfo,
|
||||
},
|
||||
|
||||
@@ -234,13 +228,9 @@ export default defineComponent({
|
||||
case 'email-settings': return defineAsyncComponent(() => import('./email-settings.vue'));
|
||||
case 'object-storage': return defineAsyncComponent(() => import('./object-storage.vue'));
|
||||
case 'security': return defineAsyncComponent(() => import('./security.vue'));
|
||||
case 'bot-protection': return defineAsyncComponent(() => import('./bot-protection.vue'));
|
||||
case 'service-worker': return defineAsyncComponent(() => import('./service-worker.vue'));
|
||||
case 'relays': return defineAsyncComponent(() => import('./relays.vue'));
|
||||
case 'integrations': return defineAsyncComponent(() => import('./integrations.vue'));
|
||||
case 'integrations/twitter': return defineAsyncComponent(() => import('./integrations-twitter.vue'));
|
||||
case 'integrations/github': return defineAsyncComponent(() => import('./integrations-github.vue'));
|
||||
case 'integrations/discord': return defineAsyncComponent(() => import('./integrations-discord.vue'));
|
||||
case 'instance-block': return defineAsyncComponent(() => import('./instance-block.vue'));
|
||||
case 'proxy-account': return defineAsyncComponent(() => import('./proxy-account.vue'));
|
||||
case 'other-settings': return defineAsyncComponent(() => import('./other-settings.vue'));
|
||||
|
@@ -1,39 +1,29 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense :p="init">
|
||||
<FormTextarea v-model="blockedHosts">
|
||||
<FormTextarea v-model="blockedHosts" class="_formBlock">
|
||||
<span>{{ $ts.blockedInstances }}</span>
|
||||
<template #desc>{{ $ts.blockedInstancesDescription }}</template>
|
||||
<template #caption>{{ $ts.blockedInstancesDescription }}</template>
|
||||
</FormTextarea>
|
||||
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormTextarea from '@/components/debobigego/textarea.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormSwitch,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormButton,
|
||||
FormTextarea,
|
||||
FormInfo,
|
||||
FormSuspense,
|
||||
},
|
||||
|
||||
|
@@ -1,291 +0,0 @@
|
||||
<template>
|
||||
<XModalWindow ref="dialog"
|
||||
:width="520"
|
||||
:height="500"
|
||||
@close="$refs.dialog.close()"
|
||||
@closed="$emit('closed')"
|
||||
>
|
||||
<template #header>{{ instance.host }}</template>
|
||||
<div class="mk-instance-info">
|
||||
<div class="_table section">
|
||||
<div class="_row">
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.software }}</div>
|
||||
<div class="_data">{{ instance.softwareName || '?' }}</div>
|
||||
</div>
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.version }}</div>
|
||||
<div class="_data">{{ instance.softwareVersion || '?' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_table data section">
|
||||
<div class="_row">
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.registeredAt }}</div>
|
||||
<div class="_data">{{ new Date(instance.caughtAt).toLocaleString() }} (<MkTime :time="instance.caughtAt"/>)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_row">
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.following }}</div>
|
||||
<button class="_data _textButton" @click="showFollowing()">{{ number(instance.followingCount) }}</button>
|
||||
</div>
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.followers }}</div>
|
||||
<button class="_data _textButton" @click="showFollowers()">{{ number(instance.followersCount) }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_row">
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.users }}</div>
|
||||
<button class="_data _textButton" @click="showUsers()">{{ number(instance.usersCount) }}</button>
|
||||
</div>
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.notes }}</div>
|
||||
<div class="_data">{{ number(instance.notesCount) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_row">
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.files }}</div>
|
||||
<div class="_data">{{ number(instance.driveFiles) }}</div>
|
||||
</div>
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.storageUsage }}</div>
|
||||
<div class="_data">{{ bytes(instance.driveUsage) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_row">
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.latestRequestSentAt }}</div>
|
||||
<div class="_data"><MkTime v-if="instance.latestRequestSentAt" :time="instance.latestRequestSentAt"/><span v-else>N/A</span></div>
|
||||
</div>
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.latestStatus }}</div>
|
||||
<div class="_data">{{ instance.latestStatus ? instance.latestStatus : 'N/A' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_row">
|
||||
<div class="_cell">
|
||||
<div class="_label">{{ $ts.latestRequestReceivedAt }}</div>
|
||||
<div class="_data"><MkTime v-if="instance.latestRequestReceivedAt" :time="instance.latestRequestReceivedAt"/><span v-else>N/A</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart">
|
||||
<div class="header">
|
||||
<span class="label">{{ $ts.charts }}</span>
|
||||
<div class="selects">
|
||||
<MkSelect v-model="chartSrc" style="margin: 0; flex: 1;">
|
||||
<option value="instance-requests">{{ $ts._instanceCharts.requests }}</option>
|
||||
<option value="instance-users">{{ $ts._instanceCharts.users }}</option>
|
||||
<option value="instance-users-total">{{ $ts._instanceCharts.usersTotal }}</option>
|
||||
<option value="instance-notes">{{ $ts._instanceCharts.notes }}</option>
|
||||
<option value="instance-notes-total">{{ $ts._instanceCharts.notesTotal }}</option>
|
||||
<option value="instance-ff">{{ $ts._instanceCharts.ff }}</option>
|
||||
<option value="instance-ff-total">{{ $ts._instanceCharts.ffTotal }}</option>
|
||||
<option value="instance-drive-usage">{{ $ts._instanceCharts.cacheSize }}</option>
|
||||
<option value="instance-drive-usage-total">{{ $ts._instanceCharts.cacheSizeTotal }}</option>
|
||||
<option value="instance-drive-files">{{ $ts._instanceCharts.files }}</option>
|
||||
<option value="instance-drive-files-total">{{ $ts._instanceCharts.filesTotal }}</option>
|
||||
</MkSelect>
|
||||
<MkSelect v-model="chartSpan" style="margin: 0;">
|
||||
<option value="hour">{{ $ts.perHour }}</option>
|
||||
<option value="day">{{ $ts.perDay }}</option>
|
||||
</MkSelect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart">
|
||||
<MkChart :src="chartSrc" :span="chartSpan" :limit="90" :detailed="true"></MkChart>
|
||||
</div>
|
||||
</div>
|
||||
<div class="operations section">
|
||||
<span class="label">{{ $ts.operations }}</span>
|
||||
<MkSwitch v-model="isSuspended" class="switch">{{ $ts.stopActivityDelivery }}</MkSwitch>
|
||||
<MkSwitch :model-value="isBlocked" class="switch" @update:modelValue="changeBlock">{{ $ts.blockThisInstance }}</MkSwitch>
|
||||
<details>
|
||||
<summary>{{ $ts.deleteAllFiles }}</summary>
|
||||
<MkButton style="margin: 0.5em 0 0.5em 0;" @click="deleteAllFiles()"><i class="fas fa-trash-alt"></i> {{ $ts.deleteAllFiles }}</MkButton>
|
||||
</details>
|
||||
<details>
|
||||
<summary>{{ $ts.removeAllFollowing }}</summary>
|
||||
<MkButton style="margin: 0.5em 0 0.5em 0;" @click="removeAllFollowing()"><i class="fas fa-minus-circle"></i> {{ $ts.removeAllFollowing }}</MkButton>
|
||||
<MkInfo warn>{{ $t('removeAllFollowingDescription', { host: instance.host }) }}</MkInfo>
|
||||
</details>
|
||||
</div>
|
||||
<details class="metadata section">
|
||||
<summary class="label">{{ $ts.metadata }}</summary>
|
||||
<pre><code>{{ JSON.stringify(instance, null, 2) }}</code></pre>
|
||||
</details>
|
||||
</div>
|
||||
</XModalWindow>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, markRaw } from 'vue';
|
||||
import XModalWindow from '@/components/ui/modal-window.vue';
|
||||
import MkSelect from '@/components/form/select.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkSwitch from '@/components/form/switch.vue';
|
||||
import MkInfo from '@/components/ui/info.vue';
|
||||
import MkChart from '@/components/chart.vue';
|
||||
import bytes from '@/filters/bytes';
|
||||
import number from '@/filters/number';
|
||||
import * as os from '@/os';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
XModalWindow,
|
||||
MkSelect,
|
||||
MkButton,
|
||||
MkSwitch,
|
||||
MkInfo,
|
||||
MkChart,
|
||||
},
|
||||
|
||||
props: {
|
||||
instance: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['closed'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
isSuspended: this.instance.isSuspended,
|
||||
chartSrc: 'requests',
|
||||
chartSpan: 'hour',
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
meta() {
|
||||
return this.$instance;
|
||||
},
|
||||
|
||||
isBlocked() {
|
||||
return this.meta && this.meta.blockedHosts && this.meta.blockedHosts.includes(this.instance.host);
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
isSuspended() {
|
||||
os.api('admin/federation/update-instance', {
|
||||
host: this.instance.host,
|
||||
isSuspended: this.isSuspended
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
changeBlock(e) {
|
||||
os.api('admin/update-meta', {
|
||||
blockedHosts: this.isBlocked ? this.meta.blockedHosts.concat([this.instance.host]) : this.meta.blockedHosts.filter(x => x !== this.instance.host)
|
||||
});
|
||||
},
|
||||
|
||||
removeAllFollowing() {
|
||||
os.apiWithDialog('admin/federation/remove-all-following', {
|
||||
host: this.instance.host
|
||||
});
|
||||
},
|
||||
|
||||
deleteAllFiles() {
|
||||
os.apiWithDialog('admin/federation/delete-all-files', {
|
||||
host: this.instance.host
|
||||
});
|
||||
},
|
||||
|
||||
showFollowing() {
|
||||
// TODO: ページ遷移
|
||||
},
|
||||
|
||||
showFollowers() {
|
||||
// TODO: ページ遷移
|
||||
},
|
||||
|
||||
showUsers() {
|
||||
// TODO: ページ遷移
|
||||
},
|
||||
|
||||
bytes,
|
||||
|
||||
number
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mk-instance-info {
|
||||
overflow: auto;
|
||||
|
||||
> .section {
|
||||
padding: 16px 32px;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top: solid 0.5px var(--divider);
|
||||
}
|
||||
}
|
||||
|
||||
> .chart {
|
||||
border-top: solid 0.5px var(--divider);
|
||||
padding: 16px 0 12px 0;
|
||||
|
||||
> .header {
|
||||
padding: 0 32px;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
> .label {
|
||||
font-size: 80%;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
> .selects {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
> .chart {
|
||||
padding: 0 16px;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .operations {
|
||||
> .label {
|
||||
font-size: 80%;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
> .switch {
|
||||
margin: 16px 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .metadata {
|
||||
> .label {
|
||||
font-size: 80%;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
> pre > code {
|
||||
display: block;
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,37 +1,36 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormSuspense :p="init">
|
||||
<FormSwitch v-model="enableDiscordIntegration">
|
||||
{{ $ts.enable }}
|
||||
<FormSuspense :p="init">
|
||||
<div class="_formRoot">
|
||||
<FormSwitch v-model="enableDiscordIntegration" class="_formBlock">
|
||||
<template #label>{{ $ts.enable }}</template>
|
||||
</FormSwitch>
|
||||
|
||||
<template v-if="enableDiscordIntegration">
|
||||
<FormInfo>Callback URL: {{ `${uri}/api/dc/cb` }}</FormInfo>
|
||||
<FormInfo class="_formBlock">Callback URL: {{ `${uri}/api/dc/cb` }}</FormInfo>
|
||||
|
||||
<FormInput v-model="discordClientId">
|
||||
<FormInput v-model="discordClientId" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
Client ID
|
||||
<template #label>Client ID</template>
|
||||
</FormInput>
|
||||
|
||||
<FormInput v-model="discordClientSecret">
|
||||
<FormInput v-model="discordClientSecret" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
Client Secret
|
||||
<template #label>Client Secret</template>
|
||||
</FormInput>
|
||||
</template>
|
||||
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormInfo from '@/components/ui/info.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
@@ -40,7 +39,6 @@ export default defineComponent({
|
||||
components: {
|
||||
FormSwitch,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormInfo,
|
||||
FormButton,
|
||||
FormSuspense,
|
@@ -1,37 +1,36 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormSuspense :p="init">
|
||||
<FormSwitch v-model="enableGithubIntegration">
|
||||
{{ $ts.enable }}
|
||||
<FormSuspense :p="init">
|
||||
<div class="_formRoot">
|
||||
<FormSwitch v-model="enableGithubIntegration" class="_formBlock">
|
||||
<template #label>{{ $ts.enable }}</template>
|
||||
</FormSwitch>
|
||||
|
||||
<template v-if="enableGithubIntegration">
|
||||
<FormInfo>Callback URL: {{ `${uri}/api/gh/cb` }}</FormInfo>
|
||||
<FormInfo class="_formBlock">Callback URL: {{ `${uri}/api/gh/cb` }}</FormInfo>
|
||||
|
||||
<FormInput v-model="githubClientId">
|
||||
<FormInput v-model="githubClientId" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
Client ID
|
||||
<template #label>Client ID</template>
|
||||
</FormInput>
|
||||
|
||||
<FormInput v-model="githubClientSecret">
|
||||
<FormInput v-model="githubClientSecret" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
Client Secret
|
||||
<template #label>Client Secret</template>
|
||||
</FormInput>
|
||||
</template>
|
||||
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormInfo from '@/components/ui/info.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
@@ -40,7 +39,6 @@ export default defineComponent({
|
||||
components: {
|
||||
FormSwitch,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormInfo,
|
||||
FormButton,
|
||||
FormSuspense,
|
@@ -1,37 +1,36 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormSuspense :p="init">
|
||||
<FormSwitch v-model="enableTwitterIntegration">
|
||||
{{ $ts.enable }}
|
||||
<FormSuspense :p="init">
|
||||
<div class="_formRoot">
|
||||
<FormSwitch v-model="enableTwitterIntegration" class="_formBlock">
|
||||
<template #label>{{ $ts.enable }}</template>
|
||||
</FormSwitch>
|
||||
|
||||
<template v-if="enableTwitterIntegration">
|
||||
<FormInfo>Callback URL: {{ `${uri}/api/tw/cb` }}</FormInfo>
|
||||
<FormInfo class="_formBlock">Callback URL: {{ `${uri}/api/tw/cb` }}</FormInfo>
|
||||
|
||||
<FormInput v-model="twitterConsumerKey">
|
||||
<FormInput v-model="twitterConsumerKey" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
Consumer Key
|
||||
<template #label>Consumer Key</template>
|
||||
</FormInput>
|
||||
|
||||
<FormInput v-model="twitterConsumerSecret">
|
||||
<FormInput v-model="twitterConsumerSecret" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
Consumer Secret
|
||||
<template #label>Consumer Secret</template>
|
||||
</FormInput>
|
||||
</template>
|
||||
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormInfo from '@/components/ui/info.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
@@ -40,7 +39,6 @@ export default defineComponent({
|
||||
components: {
|
||||
FormSwitch,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormInfo,
|
||||
FormButton,
|
||||
FormSuspense,
|
@@ -1,46 +1,48 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense :p="init">
|
||||
<FormLink to="/admin/integrations/twitter">
|
||||
<i class="fab fa-twitter"></i> Twitter
|
||||
<FormFolder class="_formBlock">
|
||||
<template #icon><i class="fab fa-twitter"></i></template>
|
||||
<template #label>Twitter</template>
|
||||
<template #suffix>{{ enableTwitterIntegration ? $ts.enabled : $ts.disabled }}</template>
|
||||
</FormLink>
|
||||
<FormLink to="/admin/integrations/github">
|
||||
<i class="fab fa-github"></i> GitHub
|
||||
<XTwitter/>
|
||||
</FormFolder>
|
||||
<FormFolder to="/admin/integrations/github" class="_formBlock">
|
||||
<template #icon><i class="fab fa-github"></i></template>
|
||||
<template #label>GitHub</template>
|
||||
<template #suffix>{{ enableGithubIntegration ? $ts.enabled : $ts.disabled }}</template>
|
||||
</FormLink>
|
||||
<FormLink to="/admin/integrations/discord">
|
||||
<i class="fab fa-discord"></i> Discord
|
||||
<XGithub/>
|
||||
</FormFolder>
|
||||
<FormFolder to="/admin/integrations/discord" class="_formBlock">
|
||||
<template #icon><i class="fab fa-discord"></i></template>
|
||||
<template #label>Discord</template>
|
||||
<template #suffix>{{ enableDiscordIntegration ? $ts.enabled : $ts.disabled }}</template>
|
||||
</FormLink>
|
||||
<XDiscord/>
|
||||
</FormFolder>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormTextarea from '@/components/debobigego/textarea.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormFolder from '@/components/form/folder.vue';
|
||||
import FormSecion from '@/components/form/section.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import XTwitter from './integrations.twitter.vue';
|
||||
import XGithub from './integrations.github.vue';
|
||||
import XDiscord from './integrations.discord.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormLink,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormButton,
|
||||
FormTextarea,
|
||||
FormInfo,
|
||||
FormFolder,
|
||||
FormSecion,
|
||||
FormSuspense,
|
||||
XTwitter,
|
||||
XGithub,
|
||||
XDiscord,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
@@ -76,7 +76,6 @@ import MkwFederation from '../../widgets/federation.vue';
|
||||
import { version, url } from '@/config';
|
||||
import bytes from '@/filters/bytes';
|
||||
import number from '@/filters/number';
|
||||
import MkInstanceInfo from './instance.vue';
|
||||
|
||||
Chart.register(
|
||||
ArcElement,
|
||||
|
@@ -1,34 +1,31 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense :p="init">
|
||||
<FormGroup>
|
||||
<FormInput v-model="summalyProxy">
|
||||
<FormSection>
|
||||
<FormInput v-model="summalyProxy" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-link"></i></template>
|
||||
Summaly Proxy URL
|
||||
<template #label>Summaly Proxy URL</template>
|
||||
</FormInput>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<FormInput v-model="deeplAuthKey">
|
||||
</FormSection>
|
||||
<FormSection>
|
||||
<FormInput v-model="deeplAuthKey" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
DeepL Auth Key
|
||||
<template #label>DeepL Auth Key</template>
|
||||
</FormInput>
|
||||
<FormSwitch v-model="deeplIsPro">
|
||||
Pro account
|
||||
<FormSwitch v-model="deeplIsPro" class="_formBlock">
|
||||
<template #label>Pro account</template>
|
||||
</FormSwitch>
|
||||
</FormGroup>
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormSection>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
@@ -37,9 +34,7 @@ export default defineComponent({
|
||||
components: {
|
||||
FormSwitch,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormButton,
|
||||
FormSection,
|
||||
FormSuspense,
|
||||
},
|
||||
|
||||
@@ -51,6 +46,12 @@ export default defineComponent({
|
||||
title: this.$ts.other,
|
||||
icon: 'fas fa-cogs',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
asFullButton: true,
|
||||
icon: 'fas fa-check',
|
||||
text: this.$ts.save,
|
||||
handler: this.save,
|
||||
}],
|
||||
},
|
||||
summalyProxy: '',
|
||||
deeplAuthKey: '',
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
<MkContainer :foldable="true" class="charts">
|
||||
<template #header><i class="fas fa-chart-bar"></i>{{ $ts.charts }}</template>
|
||||
<div style="padding-top: 12px;">
|
||||
<div style="padding: 12px;">
|
||||
<MkInstanceStats :chart-limit="500" :detailed="true"/>
|
||||
</div>
|
||||
</MkContainer>
|
||||
@@ -67,7 +67,6 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, markRaw, version as vueVersion } from 'vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import MkInstanceStats from '@/components/instance-stats.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkSelect from '@/components/form/select.vue';
|
||||
@@ -78,7 +77,6 @@ import MkQueueChart from '@/components/queue-chart.vue';
|
||||
import { version, url } from '@/config';
|
||||
import bytes from '@/filters/bytes';
|
||||
import number from '@/filters/number';
|
||||
import MkInstanceInfo from './instance.vue';
|
||||
import XMetrics from './metrics.vue';
|
||||
import * as os from '@/os';
|
||||
import { stream } from '@/stream';
|
||||
@@ -87,7 +85,6 @@ import * as symbols from '@/symbols';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MkNumberDiff,
|
||||
FormKeyValueView,
|
||||
MkInstanceStats,
|
||||
MkContainer,
|
||||
MkFolder,
|
||||
@@ -161,9 +158,7 @@ export default defineComponent({
|
||||
host: q
|
||||
});
|
||||
}
|
||||
os.popup(MkInstanceInfo, {
|
||||
instance: instance
|
||||
}, {}, 'closed');
|
||||
// TODO
|
||||
},
|
||||
|
||||
bytes,
|
||||
|
@@ -1,42 +1,32 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense :p="init">
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.proxyAccount }}</template>
|
||||
<template #value>{{ proxyAccount ? `@${proxyAccount.username}` : $ts.none }}</template>
|
||||
</FormKeyValueView>
|
||||
<template #caption>{{ $ts.proxyAccountDescription }}</template>
|
||||
</FormGroup>
|
||||
<MkInfo class="_formBlock">{{ $ts.proxyAccountDescription }}</MkInfo>
|
||||
<MkKeyValue class="_formBlock">
|
||||
<template #key>{{ $ts.proxyAccount }}</template>
|
||||
<template #value>{{ proxyAccount ? `@${proxyAccount.username}` : $ts.none }}</template>
|
||||
</MkKeyValue>
|
||||
|
||||
<FormButton primary @click="chooseProxyAccount">{{ $ts.selectAccount }}</FormButton>
|
||||
<FormButton primary class="_formBlock" @click="chooseProxyAccount">{{ $ts.selectAccount }}</FormButton>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormTextarea from '@/components/debobigego/textarea.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import MkKeyValue from '@/components/key-value.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import MkInfo from '@/components/ui/info.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormKeyValueView,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
MkKeyValue,
|
||||
FormButton,
|
||||
FormTextarea,
|
||||
FormInfo,
|
||||
MkInfo,
|
||||
FormSuspense,
|
||||
},
|
||||
|
||||
|
@@ -1,29 +1,25 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<MkSpacer :content-max="800">
|
||||
<XQueue :connection="connection" domain="inbox">
|
||||
<template #title>In</template>
|
||||
</XQueue>
|
||||
<XQueue :connection="connection" domain="deliver">
|
||||
<template #title>Out</template>
|
||||
</XQueue>
|
||||
<FormButton danger @click="clear()"><i class="fas fa-trash-alt"></i> {{ $ts.clearQueue }}</FormButton>
|
||||
</FormBase>
|
||||
<MkButton danger @click="clear()"><i class="fas fa-trash-alt"></i> {{ $ts.clearQueue }}</MkButton>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, markRaw } from 'vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import XQueue from './queue.chart.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import * as os from '@/os';
|
||||
import { stream } from '@/stream';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormButton,
|
||||
MkButton,
|
||||
XQueue,
|
||||
},
|
||||
|
@@ -1,32 +1,27 @@
|
||||
<template>
|
||||
<FormBase class="relaycxt">
|
||||
<FormButton primary @click="addRelay"><i class="fas fa-plus"></i> {{ $ts.addRelay }}</FormButton>
|
||||
|
||||
<div v-for="relay in relays" :key="relay.inbox" class="_debobigegoItem">
|
||||
<div class="_debobigegoPanel" style="padding: 16px;">
|
||||
<div>{{ relay.inbox }}</div>
|
||||
<div>{{ $t(`_relayStatus.${relay.status}`) }}</div>
|
||||
<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="fas fa-trash-alt"></i> {{ $ts.remove }}</MkButton>
|
||||
<MkSpacer :content-max="800">
|
||||
<div v-for="relay in relays" :key="relay.inbox" class="relaycxt _panel _block" style="padding: 16px;">
|
||||
<div>{{ relay.inbox }}</div>
|
||||
<div class="status">
|
||||
<i v-if="relay.status === 'accepted'" class="fas fa-check icon accepted"></i>
|
||||
<i v-else-if="relay.status === 'rejected'" class="fas fa-ban icon rejected"></i>
|
||||
<i v-else class="fas fa-clock icon requesting"></i>
|
||||
<span>{{ $t(`_relayStatus.${relay.status}`) }}</span>
|
||||
</div>
|
||||
<MkButton class="button" inline danger @click="remove(relay.inbox)"><i class="fas fa-trash-alt"></i> {{ $ts.remove }}</MkButton>
|
||||
</div>
|
||||
</FormBase>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkInput from '@/components/form/input.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormButton,
|
||||
MkButton,
|
||||
MkInput,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
@@ -37,6 +32,12 @@ export default defineComponent({
|
||||
title: this.$ts.relays,
|
||||
icon: 'fas fa-globe',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
asFullButton: true,
|
||||
icon: 'fas fa-plus',
|
||||
text: this.$ts.addRelay,
|
||||
handler: this.addRelay,
|
||||
}],
|
||||
},
|
||||
relays: [],
|
||||
inbox: '',
|
||||
@@ -94,5 +95,22 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.relaycxt {
|
||||
> .status {
|
||||
margin: 8px 0;
|
||||
|
||||
> .icon {
|
||||
width: 1em;
|
||||
margin-right: 0.75em;
|
||||
|
||||
&.accepted {
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
&.rejected {
|
||||
color: var(--error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -2,12 +2,15 @@
|
||||
<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense :p="init">
|
||||
<div class="_formRoot">
|
||||
<FormLink to="/admin/bot-protection" class="_formBlock">
|
||||
<i class="fas fa-shield-alt"></i> {{ $ts.botProtection }}
|
||||
<FormFolder class="_formBlock">
|
||||
<template #icon><i class="fas fa-shield-alt"></i></template>
|
||||
<template #label>{{ $ts.botProtection }}</template>
|
||||
<template v-if="enableHcaptcha" #suffix>hCaptcha</template>
|
||||
<template v-else-if="enableRecaptcha" #suffix>reCAPTCHA</template>
|
||||
<template v-else #suffix>{{ $ts.none }} ({{ $ts.notRecommended }})</template>
|
||||
</FormLink>
|
||||
|
||||
<XBotProtection/>
|
||||
</FormFolder>
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</MkSpacer>
|
||||
@@ -15,22 +18,24 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import FormFolder from '@/components/form/folder.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormInfo from '@/components/ui/info.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import XBotProtection from './bot-protection.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormLink,
|
||||
FormFolder,
|
||||
FormSwitch,
|
||||
FormInfo,
|
||||
FormSection,
|
||||
FormSuspense,
|
||||
XBotProtection,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
@@ -1,36 +1,34 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<MkSpacer :content-max="700" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense :p="init">
|
||||
<FormSwitch v-model="enableServiceWorker">
|
||||
{{ $ts.enableServiceworker }}
|
||||
<template #desc>{{ $ts.serviceworkerInfo }}</template>
|
||||
<FormSwitch v-model="enableServiceWorker" class="_formBlock">
|
||||
<template #label>{{ $ts.enableServiceworker }}</template>
|
||||
<template #caption>{{ $ts.serviceworkerInfo }}</template>
|
||||
</FormSwitch>
|
||||
|
||||
<template v-if="enableServiceWorker">
|
||||
<FormInput v-model="swPublicKey">
|
||||
<FormInput v-model="swPublicKey" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
Public key
|
||||
<template #label>Public key</template>
|
||||
</FormInput>
|
||||
|
||||
<FormInput v-model="swPrivateKey">
|
||||
<FormInput v-model="swPrivateKey" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-key"></i></template>
|
||||
Private key
|
||||
<template #label>Private key</template>
|
||||
</FormInput>
|
||||
</template>
|
||||
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
<FormButton primary class="_formBlock" @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { fetchInstance } from '@/instance';
|
||||
@@ -39,8 +37,6 @@ export default defineComponent({
|
||||
components: {
|
||||
FormSwitch,
|
||||
FormInput,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormButton,
|
||||
FormSuspense,
|
||||
},
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<div>
|
||||
<FormSuspense :p="init">
|
||||
<FormInput v-model="title">
|
||||
<span>{{ $ts.title }}</span>
|
||||
<template #label>{{ $ts.title }}</template>
|
||||
</FormInput>
|
||||
|
||||
<FormTextarea v-model="description" :max="500">
|
||||
<span>{{ $ts.description }}</span>
|
||||
<template #label>{{ $ts.description }}</template>
|
||||
</FormTextarea>
|
||||
|
||||
<FormGroup>
|
||||
@@ -24,19 +24,17 @@
|
||||
|
||||
<FormButton v-if="postId" danger @click="del"><i class="fas fa-trash-alt"></i> {{ $ts.delete }}</FormButton>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormTextarea from '@/components/debobigego/textarea.vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormTuple from '@/components/debobigego/tuple.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormGroup from '@/components/form/group.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import { selectFiles } from '@/scripts/select-file';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
@@ -47,7 +45,6 @@ export default defineComponent({
|
||||
FormInput,
|
||||
FormTextarea,
|
||||
FormSwitch,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormSuspense,
|
||||
},
|
||||
|
@@ -1,70 +1,71 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormGroup v-if="instance">
|
||||
<template #label>{{ instance.host }}</template>
|
||||
<FormGroup>
|
||||
<div class="_debobigegoItem">
|
||||
<div class="_debobigegoPanel fnfelxur">
|
||||
<img :src="instance.iconUrl || instance.faviconUrl" alt="" class="icon"/>
|
||||
</div>
|
||||
</div>
|
||||
<FormKeyValueView>
|
||||
<template #key>Name</template>
|
||||
<template #value><span class="_monospace">{{ instance.name || `(${$ts.unknown})` }}</span></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<MkSpacer :content-max="600" :margin-min="16" :margin-max="32">
|
||||
<div v-if="instance" class="_formRoot">
|
||||
<div class="fnfelxur">
|
||||
<img :src="instance.iconUrl || instance.faviconUrl" alt="" class="icon"/>
|
||||
</div>
|
||||
<MkKeyValue :copy="host" oneline style="margin: 1em 0;">
|
||||
<template #key>Host</template>
|
||||
<template #value><span class="_monospace"><MkLink :url="`https://${host}`">{{ host }}</MkLink></span></template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>Name</template>
|
||||
<template #value>{{ instance.name || `(${$ts.unknown})` }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ $ts.description }}</template>
|
||||
<template #value>{{ instance.description }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.software }}</template>
|
||||
<template #value><span class="_monospace">{{ instance.softwareName || `(${$ts.unknown})` }} / {{ instance.softwareVersion || `(${$ts.unknown})` }}</span></template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.administrator }}</template>
|
||||
<template #value>{{ instance.maintainerName || `(${$ts.unknown})` }} ({{ instance.maintainerEmail || `(${$ts.unknown})` }})</template>
|
||||
</MkKeyValue>
|
||||
|
||||
<FormButton v-if="$i.isAdmin || $i.isModerator" primary @click="info">{{ $ts.settings }}</FormButton>
|
||||
<FormSection v-if="iAmModerator">
|
||||
<template #label>Moderation</template>
|
||||
<FormSwitch v-model="suspended" class="_formBlock" @update:modelValue="toggleSuspend">{{ $ts.stopActivityDelivery }}</FormSwitch>
|
||||
<FormSwitch :model-value="isBlocked" class="switch" @update:modelValue="changeBlock">{{ $ts.blockThisInstance }}</FormSwitch>
|
||||
</FormSection>
|
||||
|
||||
<FormTextarea readonly :value="instance.description">
|
||||
<span>{{ $ts.description }}</span>
|
||||
</FormTextarea>
|
||||
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.software }}</template>
|
||||
<template #value><span class="_monospace">{{ instance.softwareName || `(${$ts.unknown})` }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.version }}</template>
|
||||
<template #value><span class="_monospace">{{ instance.softwareVersion || `(${$ts.unknown})` }}</span></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.administrator }}</template>
|
||||
<template #value><span class="_monospace">{{ instance.maintainerName || `(${$ts.unknown})` }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.contact }}</template>
|
||||
<template #value><span class="_monospace">{{ instance.maintainerEmail || `(${$ts.unknown})` }}</span></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<FormSection>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.registeredAt }}</template>
|
||||
<template #value><MkTime mode="detail" :time="instance.caughtAt"/></template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.updatedAt }}</template>
|
||||
<template #value><MkTime mode="detail" :time="instance.infoUpdatedAt"/></template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.latestRequestSentAt }}</template>
|
||||
<template #value><MkTime v-if="instance.latestRequestSentAt" :time="instance.latestRequestSentAt"/><span v-else>N/A</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.latestStatus }}</template>
|
||||
<template #value>{{ instance.latestStatus ? instance.latestStatus : 'N/A' }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.latestRequestReceivedAt }}</template>
|
||||
<template #value><MkTime v-if="instance.latestRequestReceivedAt" :time="instance.latestRequestReceivedAt"/><span v-else>N/A</span></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
</FormSection>
|
||||
|
||||
<FormSection>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>Open Registrations</template>
|
||||
<template #value>{{ instance.openRegistrations ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<div class="_debobigegoItem">
|
||||
<div class="_debobigegoLabel">{{ $ts.statistics }}</div>
|
||||
<div class="_debobigegoPanel cmhjzshl">
|
||||
</MkKeyValue>
|
||||
</FormSection>
|
||||
|
||||
<FormSection>
|
||||
<template #label>{{ $ts.statistics }}</template>
|
||||
<div class="cmhjzshl">
|
||||
<div class="selects">
|
||||
<MkSelect v-model="chartSrc" style="margin: 0; flex: 1;">
|
||||
<MkSelect v-model="chartSrc" style="margin: 0 10px 0 0; flex: 1;">
|
||||
<option value="instance-requests">{{ $ts._instanceCharts.requests }}</option>
|
||||
<option value="instance-users">{{ $ts._instanceCharts.users }}</option>
|
||||
<option value="instance-users-total">{{ $ts._instanceCharts.usersTotal }}</option>
|
||||
@@ -83,86 +84,55 @@
|
||||
</MkSelect>
|
||||
</div>
|
||||
<div class="chart">
|
||||
<MkChart :src="chartSrc" :span="chartSpan" :limit="90" :detailed="true"></MkChart>
|
||||
<MkChart :src="chartSrc" :span="chartSpan" :limit="90" :args="{ host: host }" :detailed="true"></MkChart>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.registeredAt }}</template>
|
||||
<template #value><MkTime mode="detail" :time="instance.caughtAt"/></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.updatedAt }}</template>
|
||||
<template #value><MkTime mode="detail" :time="instance.infoUpdatedAt"/></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<FormObjectView tall :value="instance">
|
||||
<span>Raw</span>
|
||||
</FormObjectView>
|
||||
<FormGroup>
|
||||
</FormSection>
|
||||
|
||||
<MkObjectView tall :value="instance">
|
||||
</MkObjectView>
|
||||
|
||||
<FormSection>
|
||||
<template #label>Well-known resources</template>
|
||||
<FormLink :to="`https://${host}/.well-known/host-meta`" external>host-meta</FormLink>
|
||||
<FormLink :to="`https://${host}/.well-known/host-meta.json`" external>host-meta.json</FormLink>
|
||||
<FormLink :to="`https://${host}/.well-known/nodeinfo`" external>nodeinfo</FormLink>
|
||||
<FormLink :to="`https://${host}/robots.txt`" external>robots.txt</FormLink>
|
||||
<FormLink :to="`https://${host}/manifest.json`" external>manifest.json</FormLink>
|
||||
</FormGroup>
|
||||
<FormSuspense v-slot="{ result: dns }" :p="dnsPromiseFactory">
|
||||
<FormGroup>
|
||||
<template #label>DNS</template>
|
||||
<FormKeyValueView v-for="record in dns.a" :key="record">
|
||||
<template #key>A</template>
|
||||
<template #value><span class="_monospace">{{ record }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView v-for="record in dns.aaaa" :key="record">
|
||||
<template #key>AAAA</template>
|
||||
<template #value><span class="_monospace">{{ record }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView v-for="record in dns.cname" :key="record">
|
||||
<template #key>CNAME</template>
|
||||
<template #value><span class="_monospace">{{ record }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView v-for="record in dns.txt">
|
||||
<template #key>TXT</template>
|
||||
<template #value><span class="_monospace">{{ record[0] }}</span></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
</FormSuspense>
|
||||
</FormGroup>
|
||||
</FormBase>
|
||||
<FormLink :to="`https://${host}/.well-known/host-meta`" external style="margin-bottom: 8px;">host-meta</FormLink>
|
||||
<FormLink :to="`https://${host}/.well-known/host-meta.json`" external style="margin-bottom: 8px;">host-meta.json</FormLink>
|
||||
<FormLink :to="`https://${host}/.well-known/nodeinfo`" external style="margin-bottom: 8px;">nodeinfo</FormLink>
|
||||
<FormLink :to="`https://${host}/robots.txt`" external style="margin-bottom: 8px;">robots.txt</FormLink>
|
||||
<FormLink :to="`https://${host}/manifest.json`" external style="margin-bottom: 8px;">manifest.json</FormLink>
|
||||
</FormSection>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import MkChart from '@/components/chart.vue';
|
||||
import FormObjectView from '@/components/debobigego/object-view.vue';
|
||||
import FormTextarea from '@/components/debobigego/textarea.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import MkObjectView from '@/components/object-view.vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import MkLink from '@/components/link.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import MkKeyValue from '@/components/key-value.vue';
|
||||
import MkSelect from '@/components/form/select.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import * as os from '@/os';
|
||||
import number from '@/filters/number';
|
||||
import bytes from '@/filters/bytes';
|
||||
import * as symbols from '@/symbols';
|
||||
import MkInstanceInfo from '@/pages/admin/instance.vue';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormTextarea,
|
||||
FormObjectView,
|
||||
MkObjectView,
|
||||
FormButton,
|
||||
FormLink,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
FormSuspense,
|
||||
FormSection,
|
||||
FormSwitch,
|
||||
MkKeyValue,
|
||||
MkSelect,
|
||||
MkChart,
|
||||
MkLink,
|
||||
},
|
||||
|
||||
props: {
|
||||
@@ -175,8 +145,9 @@ export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.instanceInfo,
|
||||
title: this.host,
|
||||
icon: 'fas fa-info-circle',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
text: `https://${this.host}`,
|
||||
icon: 'fas fa-external-link-alt',
|
||||
@@ -186,14 +157,22 @@ export default defineComponent({
|
||||
}],
|
||||
},
|
||||
instance: null,
|
||||
dnsPromiseFactory: () => os.api('federation/dns', {
|
||||
host: this.host
|
||||
}),
|
||||
suspended: false,
|
||||
chartSrc: 'instance-requests',
|
||||
chartSpan: 'hour',
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
iAmModerator(): boolean {
|
||||
return this.$i && (this.$i.isAdmin || this.$i.isModerator);
|
||||
},
|
||||
|
||||
isBlocked() {
|
||||
return this.instance && this.$instance && this.$instance.blockedHosts && this.$instance.blockedHosts.includes(this.instance.host);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.fetch();
|
||||
},
|
||||
@@ -206,24 +185,30 @@ export default defineComponent({
|
||||
this.instance = await os.api('federation/show-instance', {
|
||||
host: this.host
|
||||
});
|
||||
this.suspended = this.instance.isSuspended;
|
||||
},
|
||||
|
||||
info() {
|
||||
os.popup(MkInstanceInfo, {
|
||||
instance: this.instance
|
||||
}, {}, 'closed');
|
||||
}
|
||||
changeBlock(e) {
|
||||
os.api('admin/update-meta', {
|
||||
blockedHosts: this.isBlocked ? this.meta.blockedHosts.concat([this.instance.host]) : this.meta.blockedHosts.filter(x => x !== this.instance.host)
|
||||
});
|
||||
},
|
||||
|
||||
async toggleSuspend(v) {
|
||||
await os.api('admin/federation/update-instance', {
|
||||
host: this.instance.host,
|
||||
isSuspended: this.suspended
|
||||
});
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.fnfelxur {
|
||||
padding: 16px;
|
||||
|
||||
> .icon {
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin: 0;
|
||||
height: 64px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
@@ -232,7 +217,7 @@ export default defineComponent({
|
||||
.cmhjzshl {
|
||||
> .selects {
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,29 +1,25 @@
|
||||
<template>
|
||||
<FormBase v-if="token">
|
||||
<FormInput v-model="password" type="password">
|
||||
<template #prefix><i class="fas fa-lock"></i></template>
|
||||
<span>{{ $ts.newPassword }}</span>
|
||||
</FormInput>
|
||||
|
||||
<FormButton primary @click="save">{{ $ts.save }}</FormButton>
|
||||
</FormBase>
|
||||
<MkSpacer v-if="token" :content-max="700" :margin-min="16" :margin-max="32">
|
||||
<div class="_formRoot">
|
||||
<FormInput v-model="password" type="password" class="_formBlock">
|
||||
<template #prefix><i class="fas fa-lock"></i></template>
|
||||
<template #label>{{ $ts.newPassword }}</template>
|
||||
</FormInput>
|
||||
|
||||
<FormButton primary class="_formBlock" @click="save">{{ $ts.save }}</FormButton>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormLink,
|
||||
FormInput,
|
||||
FormButton,
|
||||
},
|
||||
@@ -39,7 +35,8 @@ export default defineComponent({
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.resetPassword,
|
||||
icon: 'fas fa-lock'
|
||||
icon: 'fas fa-lock',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
password: '',
|
||||
}
|
||||
|
@@ -71,9 +71,6 @@ import MkButton from '@/components/ui/button.vue';
|
||||
import MkInfo from '@/components/ui/info.vue';
|
||||
import MkInput from '@/components/form/input.vue';
|
||||
import MkSwitch from '@/components/form/switch.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
|
@@ -1,144 +1,139 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormKeyValueView>
|
||||
<div class="_formRoot">
|
||||
<MkKeyValue>
|
||||
<template #key>ID</template>
|
||||
<template #value><span class="_monospace">{{ $i.id }}</span></template>
|
||||
</FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<FormSection>
|
||||
<MkKeyValue>
|
||||
<template #key>{{ $ts.registeredDate }}</template>
|
||||
<template #value><MkTime :time="$i.createdAt" mode="detail"/></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
</MkKeyValue>
|
||||
</FormSection>
|
||||
|
||||
<FormGroup v-if="stats">
|
||||
<FormSection v-if="stats">
|
||||
<template #label>{{ $ts.statistics }}</template>
|
||||
<FormKeyValueView>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.notesCount }}</template>
|
||||
<template #value>{{ number(stats.notesCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.repliesCount }}</template>
|
||||
<template #value>{{ number(stats.repliesCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.renotesCount }}</template>
|
||||
<template #value>{{ number(stats.renotesCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.repliedCount }}</template>
|
||||
<template #value>{{ number(stats.repliedCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.renotedCount }}</template>
|
||||
<template #value>{{ number(stats.renotedCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.pollVotesCount }}</template>
|
||||
<template #value>{{ number(stats.pollVotesCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.pollVotedCount }}</template>
|
||||
<template #value>{{ number(stats.pollVotedCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.sentReactionsCount }}</template>
|
||||
<template #value>{{ number(stats.sentReactionsCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.receivedReactionsCount }}</template>
|
||||
<template #value>{{ number(stats.receivedReactionsCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.noteFavoritesCount }}</template>
|
||||
<template #value>{{ number(stats.noteFavoritesCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.followingCount }}</template>
|
||||
<template #value>{{ number(stats.followingCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.followingCount }} ({{ $ts.local }})</template>
|
||||
<template #value>{{ number(stats.localFollowingCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.followingCount }} ({{ $ts.remote }})</template>
|
||||
<template #value>{{ number(stats.remoteFollowingCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.followersCount }}</template>
|
||||
<template #value>{{ number(stats.followersCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.followersCount }} ({{ $ts.local }})</template>
|
||||
<template #value>{{ number(stats.localFollowersCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.followersCount }} ({{ $ts.remote }})</template>
|
||||
<template #value>{{ number(stats.remoteFollowersCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.pageLikesCount }}</template>
|
||||
<template #value>{{ number(stats.pageLikesCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.pageLikedCount }}</template>
|
||||
<template #value>{{ number(stats.pageLikedCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.driveFilesCount }}</template>
|
||||
<template #value>{{ number(stats.driveFilesCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.driveUsage }}</template>
|
||||
<template #value>{{ bytes(stats.driveUsage) }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.reversiCount }}</template>
|
||||
<template #value>{{ number(stats.reversiCount) }}</template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
</MkKeyValue>
|
||||
</FormSection>
|
||||
|
||||
<FormGroup>
|
||||
<FormSection>
|
||||
<template #label>{{ $ts.other }}</template>
|
||||
<FormKeyValueView>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>emailVerified</template>
|
||||
<template #value>{{ $i.emailVerified ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>twoFactorEnabled</template>
|
||||
<template #value>{{ $i.twoFactorEnabled ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>securityKeys</template>
|
||||
<template #value>{{ $i.securityKeys ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>usePasswordLessLogin</template>
|
||||
<template #value>{{ $i.usePasswordLessLogin ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>isModerator</template>
|
||||
<template #value>{{ $i.isModerator ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>isAdmin</template>
|
||||
<template #value>{{ $i.isAdmin ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
</FormBase>
|
||||
</MkKeyValue>
|
||||
</FormSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import MkKeyValue from '@/components/key-value.vue';
|
||||
import * as os from '@/os';
|
||||
import number from '@/filters/number';
|
||||
import bytes from '@/filters/bytes';
|
||||
@@ -146,13 +141,8 @@ import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormSelect,
|
||||
FormSwitch,
|
||||
FormButton,
|
||||
FormLink,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
FormSection,
|
||||
MkKeyValue,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
@@ -1,41 +1,35 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<div class="_formRoot">
|
||||
<FormSuspense :p="init">
|
||||
<FormButton primary @click="addAccount"><i class="fas fa-plus"></i> {{ $ts.addAccount }}</FormButton>
|
||||
|
||||
<div v-for="account in accounts" :key="account.id" class="_debobigegoItem _button" @click="menu(account, $event)">
|
||||
<div class="_debobigegoPanel lcjjdxlm">
|
||||
<div class="avatar">
|
||||
<MkAvatar :user="account" class="avatar"/>
|
||||
<div v-for="account in accounts" :key="account.id" class="_panel _button lcjjdxlm" @click="menu(account, $event)">
|
||||
<div class="avatar">
|
||||
<MkAvatar :user="account" class="avatar"/>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="name">
|
||||
<MkUserName :user="account"/>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="name">
|
||||
<MkUserName :user="account"/>
|
||||
</div>
|
||||
<div class="acct">
|
||||
<MkAcct :user="account"/>
|
||||
</div>
|
||||
<div class="acct">
|
||||
<MkAcct :user="account"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
import { getAccounts, addAccount, login } from '@/account';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormSuspense,
|
||||
FormButton,
|
||||
},
|
||||
|
@@ -1,25 +1,20 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormButton primary @click="generateToken">{{ $ts.generateAccessToken }}</FormButton>
|
||||
<FormLink to="/settings/apps">{{ $ts.manageAccessTokens }}</FormLink>
|
||||
<FormLink to="/api-console" :behavior="isDesktop ? 'window' : null">API console</FormLink>
|
||||
</FormBase>
|
||||
<div class="_formRoot">
|
||||
<FormButton primary class="_formBlock" @click="generateToken">{{ $ts.generateAccessToken }}</FormButton>
|
||||
<FormLink to="/settings/apps" class="_formBlock">{{ $ts.manageAccessTokens }}</FormLink>
|
||||
<FormLink to="/api-console" :behavior="isDesktop ? 'window' : null" class="_formBlock">API console</FormLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormButton,
|
||||
FormLink,
|
||||
},
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<div class="_formRoot">
|
||||
<FormPagination ref="list" :pagination="pagination">
|
||||
<template #empty>
|
||||
<div class="_fullinfo">
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot="{items}">
|
||||
<div v-for="token in items" :key="token.id" class="_debobigegoPanel bfomjevm">
|
||||
<div v-for="token in items" :key="token.id" class="_panel bfomjevm">
|
||||
<img v-if="token.iconUrl" class="icon" :src="token.iconUrl" alt=""/>
|
||||
<div class="body">
|
||||
<div class="name">{{ token.name }}</div>
|
||||
@@ -34,23 +34,17 @@
|
||||
</div>
|
||||
</template>
|
||||
</FormPagination>
|
||||
</FormBase>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormPagination from '@/components/debobigego/pagination.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormPagination from '@/components/ui/pagination.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormPagination,
|
||||
},
|
||||
|
||||
|
@@ -1,25 +1,18 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormInfo warn>{{ $ts.customCssWarn }}</FormInfo>
|
||||
<div class="_formRoot">
|
||||
<FormInfo warn class="_formBlock">{{ $ts.customCssWarn }}</FormInfo>
|
||||
|
||||
<FormTextarea v-model="localCustomCss" manual-save tall class="_monospace" style="tab-size: 2;">
|
||||
<span>{{ $ts.local }}</span>
|
||||
<FormTextarea v-model="localCustomCss" manual-save tall class="_monospace _formBlock" style="tab-size: 2;">
|
||||
<template #label>CSS</template>
|
||||
</FormTextarea>
|
||||
</FormBase>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormRadios from '@/components/form/radios.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormInfo from '@/components/ui/info.vue';
|
||||
import * as os from '@/os';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
import { unisonReload } from '@/scripts/unison-reload';
|
||||
import * as symbols from '@/symbols';
|
||||
import { defaultStore } from '@/store';
|
||||
@@ -27,12 +20,6 @@ import { defaultStore } from '@/store';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormTextarea,
|
||||
FormSelect,
|
||||
FormRadios,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormLink,
|
||||
FormButton,
|
||||
FormInfo,
|
||||
},
|
||||
|
||||
|
@@ -1,42 +1,41 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<div class="_formRoot">
|
||||
<FormGroup>
|
||||
<template #label>{{ $ts.defaultNavigationBehaviour }}</template>
|
||||
<FormSwitch v-model="navWindow">{{ $ts.openInWindow }}</FormSwitch>
|
||||
</FormGroup>
|
||||
|
||||
<FormSwitch v-model="alwaysShowMainColumn">{{ $ts._deck.alwaysShowMainColumn }}</FormSwitch>
|
||||
<FormSwitch v-model="alwaysShowMainColumn" class="_formBlock">{{ $ts._deck.alwaysShowMainColumn }}</FormSwitch>
|
||||
|
||||
<FormRadios v-model="columnAlign">
|
||||
<template #desc>{{ $ts._deck.columnAlign }}</template>
|
||||
<FormRadios v-model="columnAlign" class="_formBlock">
|
||||
<template #label>{{ $ts._deck.columnAlign }}</template>
|
||||
<option value="left">{{ $ts.left }}</option>
|
||||
<option value="center">{{ $ts.center }}</option>
|
||||
</FormRadios>
|
||||
|
||||
<FormRadios v-model="columnHeaderHeight">
|
||||
<template #desc>{{ $ts._deck.columnHeaderHeight }}</template>
|
||||
<FormRadios v-model="columnHeaderHeight" class="_formBlock">
|
||||
<template #label>{{ $ts._deck.columnHeaderHeight }}</template>
|
||||
<option :value="42">{{ $ts.narrow }}</option>
|
||||
<option :value="45">{{ $ts.medium }}</option>
|
||||
<option :value="48">{{ $ts.wide }}</option>
|
||||
</FormRadios>
|
||||
|
||||
<FormInput v-model="columnMargin" type="number">
|
||||
<span>{{ $ts._deck.columnMargin }}</span>
|
||||
<FormInput v-model="columnMargin" type="number" class="_formBlock">
|
||||
<template #label>{{ $ts._deck.columnMargin }}</template>
|
||||
<template #suffix>px</template>
|
||||
</FormInput>
|
||||
|
||||
<FormLink @click="setProfile">{{ $ts._deck.profile }}<template #suffix>{{ profile }}</template></FormLink>
|
||||
</FormBase>
|
||||
<FormLink class="_formBlock" @click="setProfile">{{ $ts._deck.profile }}<template #suffix>{{ profile }}</template></FormLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormRadios from '@/components/debobigego/radios.vue';
|
||||
import FormInput from '@/components/debobigego/input.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import FormRadios from '@/components/form/radios.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormGroup from '@/components/form/group.vue';
|
||||
import { deckStore } from '@/ui/deck/deck-store';
|
||||
import * as os from '@/os';
|
||||
import { unisonReload } from '@/scripts/unison-reload';
|
||||
@@ -48,7 +47,6 @@ export default defineComponent({
|
||||
FormLink,
|
||||
FormInput,
|
||||
FormRadios,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
},
|
||||
|
||||
|
@@ -1,28 +1,23 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormInfo warn>{{ $ts._accountDelete.mayTakeTime }}</FormInfo>
|
||||
<FormInfo>{{ $ts._accountDelete.sendEmail }}</FormInfo>
|
||||
<FormButton v-if="!$i.isDeleted" danger @click="deleteAccount">{{ $ts._accountDelete.requestAccountDelete }}</FormButton>
|
||||
<div class="_formRoot">
|
||||
<FormInfo warn class="_formBlock">{{ $ts._accountDelete.mayTakeTime }}</FormInfo>
|
||||
<FormInfo class="_formBlock">{{ $ts._accountDelete.sendEmail }}</FormInfo>
|
||||
<FormButton v-if="!$i.isDeleted" danger class="_formBlock" @click="deleteAccount">{{ $ts._accountDelete.requestAccountDelete }}</FormButton>
|
||||
<FormButton v-else disabled>{{ $ts._accountDelete.inProgress }}</FormButton>
|
||||
</FormBase>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormInfo from '@/components/ui/info.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import * as os from '@/os';
|
||||
import { debug } from '@/config';
|
||||
import { signout } from '@/account';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormButton,
|
||||
FormGroup,
|
||||
FormInfo,
|
||||
},
|
||||
|
||||
@@ -35,7 +30,6 @@ export default defineComponent({
|
||||
icon: 'fas fa-exclamation-triangle',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
debug,
|
||||
}
|
||||
},
|
||||
|
||||
|
@@ -41,8 +41,6 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, onMounted, ref, watch } from 'vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
@@ -54,8 +52,6 @@ import { i18n } from '@/i18n';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormSection,
|
||||
FormLink,
|
||||
FormButton,
|
||||
FormSwitch,
|
||||
FormInput,
|
||||
},
|
||||
|
@@ -1,52 +0,0 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormButton @click="error()">error test</FormButton>
|
||||
</FormBase>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormSelect,
|
||||
FormSwitch,
|
||||
FormButton,
|
||||
FormLink,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.experimentalFeatures,
|
||||
icon: 'fas fa-flask'
|
||||
},
|
||||
stats: null
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$emit('info', this[symbols.PAGE_INFO]);
|
||||
},
|
||||
|
||||
methods: {
|
||||
error() {
|
||||
throw new Error('Test error');
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@@ -215,19 +215,9 @@ export default defineComponent({
|
||||
case 'deck': return defineAsyncComponent(() => import('./deck.vue'));
|
||||
case 'plugin': return defineAsyncComponent(() => import('./plugin.vue'));
|
||||
case 'plugin/install': return defineAsyncComponent(() => import('./plugin.install.vue'));
|
||||
case 'plugin/manage': return defineAsyncComponent(() => import('./plugin.manage.vue'));
|
||||
case 'import-export': return defineAsyncComponent(() => import('./import-export.vue'));
|
||||
case 'account-info': return defineAsyncComponent(() => import('./account-info.vue'));
|
||||
case 'update': return defineAsyncComponent(() => import('./update.vue'));
|
||||
case 'registry': return defineAsyncComponent(() => import('./registry.vue'));
|
||||
case 'delete-account': return defineAsyncComponent(() => import('./delete-account.vue'));
|
||||
case 'experimental-features': return defineAsyncComponent(() => import('./experimental-features.vue'));
|
||||
}
|
||||
if (page.value.startsWith('registry/keys/system/')) {
|
||||
return defineAsyncComponent(() => import('./registry.keys.vue'));
|
||||
}
|
||||
if (page.value.startsWith('registry/value/system/')) {
|
||||
return defineAsyncComponent(() => import('./registry.value.vue'));
|
||||
}
|
||||
return null;
|
||||
});
|
||||
@@ -235,17 +225,6 @@ export default defineComponent({
|
||||
watch(component, () => {
|
||||
pageProps.value = {};
|
||||
|
||||
if (page.value) {
|
||||
if (page.value.startsWith('registry/keys/system/')) {
|
||||
pageProps.value.scope = page.value.replace('registry/keys/system/', '').split('/');
|
||||
}
|
||||
if (page.value.startsWith('registry/value/system/')) {
|
||||
const path = page.value.replace('registry/value/system/', '').split('/');
|
||||
pageProps.value.xKey = path.pop();
|
||||
pageProps.value.scope = path;
|
||||
}
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
scroll(el.value, { top: 0 });
|
||||
});
|
||||
|
@@ -1,45 +1,39 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<div v-if="enableTwitterIntegration" class="_debobigegoItem">
|
||||
<div class="_debobigegoLabel"><i class="fab fa-twitter"></i> Twitter</div>
|
||||
<div class="_debobigegoPanel" style="padding: 16px;">
|
||||
<p v-if="integrations.twitter">{{ $ts.connectedTo }}: <a :href="`https://twitter.com/${integrations.twitter.screenName}`" rel="nofollow noopener" target="_blank">@{{ integrations.twitter.screenName }}</a></p>
|
||||
<MkButton v-if="integrations.twitter" danger @click="disconnectTwitter">{{ $ts.disconnectService }}</MkButton>
|
||||
<MkButton v-else primary @click="connectTwitter">{{ $ts.connectService }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_formRoot">
|
||||
<FormSection v-if="enableTwitterIntegration">
|
||||
<template #label><i class="fab fa-twitter"></i> Twitter</template>
|
||||
<p v-if="integrations.twitter">{{ $ts.connectedTo }}: <a :href="`https://twitter.com/${integrations.twitter.screenName}`" rel="nofollow noopener" target="_blank">@{{ integrations.twitter.screenName }}</a></p>
|
||||
<MkButton v-if="integrations.twitter" danger @click="disconnectTwitter">{{ $ts.disconnectService }}</MkButton>
|
||||
<MkButton v-else primary @click="connectTwitter">{{ $ts.connectService }}</MkButton>
|
||||
</FormSection>
|
||||
|
||||
<div v-if="enableDiscordIntegration" class="_debobigegoItem">
|
||||
<div class="_debobigegoLabel"><i class="fab fa-discord"></i> Discord</div>
|
||||
<div class="_debobigegoPanel" style="padding: 16px;">
|
||||
<p v-if="integrations.discord">{{ $ts.connectedTo }}: <a :href="`https://discord.com/users/${integrations.discord.id}`" rel="nofollow noopener" target="_blank">@{{ integrations.discord.username }}#{{ integrations.discord.discriminator }}</a></p>
|
||||
<MkButton v-if="integrations.discord" danger @click="disconnectDiscord">{{ $ts.disconnectService }}</MkButton>
|
||||
<MkButton v-else primary @click="connectDiscord">{{ $ts.connectService }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
<FormSection v-if="enableDiscordIntegration">
|
||||
<template #label><i class="fab fa-discord"></i> Discord</template>
|
||||
<p v-if="integrations.discord">{{ $ts.connectedTo }}: <a :href="`https://discord.com/users/${integrations.discord.id}`" rel="nofollow noopener" target="_blank">@{{ integrations.discord.username }}#{{ integrations.discord.discriminator }}</a></p>
|
||||
<MkButton v-if="integrations.discord" danger @click="disconnectDiscord">{{ $ts.disconnectService }}</MkButton>
|
||||
<MkButton v-else primary @click="connectDiscord">{{ $ts.connectService }}</MkButton>
|
||||
</FormSection>
|
||||
|
||||
<div v-if="enableGithubIntegration" class="_debobigegoItem">
|
||||
<div class="_debobigegoLabel"><i class="fab fa-github"></i> GitHub</div>
|
||||
<div class="_debobigegoPanel" style="padding: 16px;">
|
||||
<p v-if="integrations.github">{{ $ts.connectedTo }}: <a :href="`https://github.com/${integrations.github.login}`" rel="nofollow noopener" target="_blank">@{{ integrations.github.login }}</a></p>
|
||||
<MkButton v-if="integrations.github" danger @click="disconnectGithub">{{ $ts.disconnectService }}</MkButton>
|
||||
<MkButton v-else primary @click="connectGithub">{{ $ts.connectService }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</FormBase>
|
||||
<FormSection v-if="enableGithubIntegration">
|
||||
<template #label><i class="fab fa-github"></i> GitHub</template>
|
||||
<p v-if="integrations.github">{{ $ts.connectedTo }}: <a :href="`https://github.com/${integrations.github.login}`" rel="nofollow noopener" target="_blank">@{{ integrations.github.login }}</a></p>
|
||||
<MkButton v-if="integrations.github" danger @click="disconnectGithub">{{ $ts.disconnectService }}</MkButton>
|
||||
<MkButton v-else primary @click="connectGithub">{{ $ts.connectService }}</MkButton>
|
||||
</FormSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { apiUrl } from '@/config';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormSection,
|
||||
MkButton
|
||||
},
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<div class="_formRoot">
|
||||
<MkTab v-model="tab" style="margin-bottom: var(--margin);">
|
||||
<option value="mute">{{ $ts.mutedUsers }}</option>
|
||||
<option value="block">{{ $ts.blockedUsers }}</option>
|
||||
@@ -8,11 +8,9 @@
|
||||
<MkPagination :pagination="mutingPagination" class="muting">
|
||||
<template #empty><FormInfo>{{ $ts.noUsers }}</FormInfo></template>
|
||||
<template v-slot="{items}">
|
||||
<FormGroup>
|
||||
<FormLink v-for="mute in items" :key="mute.id" :to="userPage(mute.mutee)">
|
||||
<MkAcct :user="mute.mutee"/>
|
||||
</FormLink>
|
||||
</FormGroup>
|
||||
<FormLink v-for="mute in items" :key="mute.id" :to="userPage(mute.mutee)">
|
||||
<MkAcct :user="mute.mutee"/>
|
||||
</FormLink>
|
||||
</template>
|
||||
</MkPagination>
|
||||
</div>
|
||||
@@ -20,25 +18,21 @@
|
||||
<MkPagination :pagination="blockingPagination" class="blocking">
|
||||
<template #empty><FormInfo>{{ $ts.noUsers }}</FormInfo></template>
|
||||
<template v-slot="{items}">
|
||||
<FormGroup>
|
||||
<FormLink v-for="block in items" :key="block.id" :to="userPage(block.blockee)">
|
||||
<MkAcct :user="block.blockee"/>
|
||||
</FormLink>
|
||||
</FormGroup>
|
||||
<FormLink v-for="block in items" :key="block.id" :to="userPage(block.blockee)">
|
||||
<MkAcct :user="block.blockee"/>
|
||||
</FormLink>
|
||||
</template>
|
||||
</MkPagination>
|
||||
</div>
|
||||
</FormBase>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import MkPagination from '@/components/ui/pagination.vue';
|
||||
import MkTab from '@/components/tab.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormInfo from '@/components/ui/info.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import { userPage } from '@/filters/user';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
@@ -48,8 +42,6 @@ export default defineComponent({
|
||||
MkPagination,
|
||||
MkTab,
|
||||
FormInfo,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormLink,
|
||||
},
|
||||
|
||||
|
@@ -1,30 +1,12 @@
|
||||
<template>
|
||||
<div class="_formRoot">
|
||||
<FormLink to="/settings/update" class="_formBlock">Misskey Update</FormLink>
|
||||
|
||||
<FormSwitch :value="$i.injectFeaturedNote" @update:modelValue="onChangeInjectFeaturedNote" class="_formBlock">
|
||||
<FormSwitch :value="$i.injectFeaturedNote" class="_formBlock" @update:modelValue="onChangeInjectFeaturedNote">
|
||||
{{ $ts.showFeaturedNotesInTimeline }}
|
||||
</FormSwitch>
|
||||
|
||||
<FormSwitch v-model="reportError" class="_formBlock">{{ $ts.sendErrorReports }}<template #desc>{{ $ts.sendErrorReportsDescription }}</template></FormSwitch>
|
||||
<FormSwitch v-model="reportError" class="_formBlock">{{ $ts.sendErrorReports }}<template #caption>{{ $ts.sendErrorReportsDescription }}</template></FormSwitch>
|
||||
|
||||
<FormLink to="/settings/account-info" class="_formBlock">{{ $ts.accountInfo }}</FormLink>
|
||||
<FormLink to="/settings/experimental-features" class="_formBlock">{{ $ts.experimentalFeatures }}</FormLink>
|
||||
|
||||
<FormSection>
|
||||
<template #label>{{ $ts.developer }}</template>
|
||||
<FormSwitch v-model="debug" @update:modelValue="changeDebug" class="_formBlock">
|
||||
DEBUG MODE
|
||||
</FormSwitch>
|
||||
<template v-if="debug">
|
||||
<FormButton @click="taskmanager">Task Manager</FormButton>
|
||||
</template>
|
||||
</FormSection>
|
||||
|
||||
<FormLink to="/settings/registry" class="_formBlock"><template #icon><i class="fas fa-cogs"></i></template>{{ $ts.registry }}</FormLink>
|
||||
|
||||
<FormLink to="/bios" behavior="browser" class="_formBlock"><template #icon><i class="fas fa-door-open"></i></template>BIOS</FormLink>
|
||||
<FormLink to="/cli" behavior="browser" class="_formBlock"><template #icon><i class="fas fa-door-open"></i></template>CLI</FormLink>
|
||||
|
||||
<FormLink to="/settings/delete-account" class="_formBlock"><template #icon><i class="fas fa-exclamation-triangle"></i></template>{{ $ts.closeAccount }}</FormLink>
|
||||
</div>
|
||||
@@ -33,10 +15,8 @@
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import * as os from '@/os';
|
||||
import { debug } from '@/config';
|
||||
import { defaultStore } from '@/store';
|
||||
@@ -45,10 +25,8 @@ import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormSelect,
|
||||
FormSection,
|
||||
FormSwitch,
|
||||
FormButton,
|
||||
FormLink,
|
||||
},
|
||||
|
||||
|
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormInfo warn>{{ $ts._plugin.installWarn }}</FormInfo>
|
||||
<div class="_formRoot">
|
||||
<FormInfo warn class="_formBlock">{{ $ts._plugin.installWarn }}</FormInfo>
|
||||
|
||||
<FormGroup>
|
||||
<FormTextarea v-model="code" tall>
|
||||
<span>{{ $ts.code }}</span>
|
||||
</FormTextarea>
|
||||
</FormGroup>
|
||||
<FormTextarea v-model="code" tall class="_formBlock">
|
||||
<template #label>{{ $ts.code }}</template>
|
||||
</FormTextarea>
|
||||
|
||||
<FormButton :disabled="code == null" primary inline @click="install"><i class="fas fa-check"></i> {{ $ts.install }}</FormButton>
|
||||
</FormBase>
|
||||
<div class="_formBlock">
|
||||
<FormButton :disabled="code == null" primary inline @click="install"><i class="fas fa-check"></i> {{ $ts.install }}</FormButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -18,13 +18,8 @@ import { AiScript, parse } from '@syuilo/aiscript';
|
||||
import { serialize } from '@syuilo/aiscript/built/serializer';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormRadios from '@/components/form/radios.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormInfo from '@/components/ui/info.vue';
|
||||
import * as os from '@/os';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
import { unisonReload } from '@/scripts/unison-reload';
|
||||
@@ -33,11 +28,6 @@ import * as symbols from '@/symbols';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormTextarea,
|
||||
FormSelect,
|
||||
FormRadios,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormLink,
|
||||
FormButton,
|
||||
FormInfo,
|
||||
},
|
||||
|
@@ -1,116 +0,0 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormGroup v-for="plugin in plugins" :key="plugin.id">
|
||||
<template #label><span style="display: flex;"><b>{{ plugin.name }}</b><span style="margin-left: auto;">v{{ plugin.version }}</span></span></template>
|
||||
|
||||
<FormSwitch :modelValue="plugin.active" @update:modelValue="changeActive(plugin, $event)">{{ $ts.makeActive }}</FormSwitch>
|
||||
<div class="_debobigegoItem">
|
||||
<div class="_debobigegoPanel" style="padding: 16px;">
|
||||
<div class="_keyValue">
|
||||
<div>{{ $ts.author }}:</div>
|
||||
<div>{{ plugin.author }}</div>
|
||||
</div>
|
||||
<div class="_keyValue">
|
||||
<div>{{ $ts.description }}:</div>
|
||||
<div>{{ plugin.description }}</div>
|
||||
</div>
|
||||
<div class="_keyValue">
|
||||
<div>{{ $ts.permission }}:</div>
|
||||
<div>{{ plugin.permissions }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_debobigegoItem">
|
||||
<div class="_debobigegoPanel" style="padding: 16px;">
|
||||
<MkButton v-if="plugin.config" inline @click="config(plugin)"><i class="fas fa-cog"></i> {{ $ts.settings }}</MkButton>
|
||||
<MkButton inline danger @click="uninstall(plugin)"><i class="fas fa-trash-alt"></i> {{ $ts.uninstall }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</FormGroup>
|
||||
</FormBase>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkTextarea from '@/components/form/textarea.vue';
|
||||
import MkSelect from '@/components/form/select.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import * as os from '@/os';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
import * as symbols from '@/symbols';
|
||||
import { unisonReload } from '@/scripts/unison-reload';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MkButton,
|
||||
MkTextarea,
|
||||
MkSelect,
|
||||
FormSwitch,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts._plugin.manage,
|
||||
icon: 'fas fa-plug',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
plugins: ColdDeviceStorage.get('plugins'),
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$emit('info', this[symbols.PAGE_INFO]);
|
||||
},
|
||||
|
||||
methods: {
|
||||
uninstall(plugin) {
|
||||
ColdDeviceStorage.set('plugins', this.plugins.filter(x => x.id !== plugin.id));
|
||||
os.success();
|
||||
this.$nextTick(() => {
|
||||
unisonReload();
|
||||
});
|
||||
},
|
||||
|
||||
// TODO: この処理をstore側にactionとして移動し、設定画面を開くAiScriptAPIを実装できるようにする
|
||||
async config(plugin) {
|
||||
const config = plugin.config;
|
||||
for (const key in plugin.configData) {
|
||||
config[key].default = plugin.configData[key];
|
||||
}
|
||||
|
||||
const { canceled, result } = await os.form(plugin.name, config);
|
||||
if (canceled) return;
|
||||
|
||||
const plugins = ColdDeviceStorage.get('plugins');
|
||||
plugins.find(p => p.id === plugin.id).configData = result;
|
||||
ColdDeviceStorage.set('plugins', plugins);
|
||||
|
||||
this.$nextTick(() => {
|
||||
location.reload();
|
||||
});
|
||||
},
|
||||
|
||||
changeActive(plugin, active) {
|
||||
const plugins = ColdDeviceStorage.get('plugins');
|
||||
plugins.find(p => p.id === plugin.id).active = active;
|
||||
ColdDeviceStorage.set('plugins', plugins);
|
||||
|
||||
this.$nextTick(() => {
|
||||
location.reload();
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
@@ -1,23 +1,54 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<div class="_formRoot">
|
||||
<FormLink to="/settings/plugin/install"><template #icon><i class="fas fa-download"></i></template>{{ $ts._plugin.install }}</FormLink>
|
||||
<FormLink to="/settings/plugin/manage"><template #icon><i class="fas fa-folder-open"></i></template>{{ $ts._plugin.manage }}<template #suffix>{{ plugins }}</template></FormLink>
|
||||
</FormBase>
|
||||
|
||||
<FormSection>
|
||||
<template #label>{{ $ts.manage }}</template>
|
||||
<div v-for="plugin in plugins" :key="plugin.id" class="_formBlock _panel" style="padding: 20px;">
|
||||
<span style="display: flex;"><b>{{ plugin.name }}</b><span style="margin-left: auto;">v{{ plugin.version }}</span></span>
|
||||
|
||||
<FormSwitch class="_formBlock" :modelValue="plugin.active" @update:modelValue="changeActive(plugin, $event)">{{ $ts.makeActive }}</FormSwitch>
|
||||
|
||||
<MkKeyValue class="_formBlock">
|
||||
<template #key>{{ $ts.author }}</template>
|
||||
<template #value>{{ plugin.author }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue class="_formBlock">
|
||||
<template #key>{{ $ts.description }}</template>
|
||||
<template #value>{{ plugin.description }}</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue class="_formBlock">
|
||||
<template #key>{{ $ts.permission }}</template>
|
||||
<template #value>{{ plugin.permission }}</template>
|
||||
</MkKeyValue>
|
||||
|
||||
<div style="display: flex; gap: var(--margin); flex-wrap: wrap;">
|
||||
<MkButton v-if="plugin.config" inline @click="config(plugin)"><i class="fas fa-cog"></i> {{ $ts.settings }}</MkButton>
|
||||
<MkButton inline danger @click="uninstall(plugin)"><i class="fas fa-trash-alt"></i> {{ $ts.uninstall }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</FormSection>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkKeyValue from '@/components/key-value.vue';
|
||||
import * as os from '@/os';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormLink,
|
||||
FormSwitch,
|
||||
FormSection,
|
||||
MkButton,
|
||||
MkKeyValue,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
@@ -29,13 +60,52 @@ export default defineComponent({
|
||||
icon: 'fas fa-plug',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
plugins: ColdDeviceStorage.get('plugins').length,
|
||||
plugins: ColdDeviceStorage.get('plugins'),
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$emit('info', this[symbols.PAGE_INFO]);
|
||||
},
|
||||
|
||||
methods: {
|
||||
uninstall(plugin) {
|
||||
ColdDeviceStorage.set('plugins', this.plugins.filter(x => x.id !== plugin.id));
|
||||
os.success();
|
||||
this.$nextTick(() => {
|
||||
unisonReload();
|
||||
});
|
||||
},
|
||||
|
||||
// TODO: この処理をstore側にactionとして移動し、設定画面を開くAiScriptAPIを実装できるようにする
|
||||
async config(plugin) {
|
||||
const config = plugin.config;
|
||||
for (const key in plugin.configData) {
|
||||
config[key].default = plugin.configData[key];
|
||||
}
|
||||
|
||||
const { canceled, result } = await os.form(plugin.name, config);
|
||||
if (canceled) return;
|
||||
|
||||
const plugins = ColdDeviceStorage.get('plugins');
|
||||
plugins.find(p => p.id === plugin.id).configData = result;
|
||||
ColdDeviceStorage.set('plugins', plugins);
|
||||
|
||||
this.$nextTick(() => {
|
||||
location.reload();
|
||||
});
|
||||
},
|
||||
|
||||
changeActive(plugin, active) {
|
||||
const plugins = ColdDeviceStorage.get('plugins');
|
||||
plugins.find(p => p.id === plugin.id).active = active;
|
||||
ColdDeviceStorage.set('plugins', plugins);
|
||||
|
||||
this.$nextTick(() => {
|
||||
location.reload();
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@@ -1,114 +0,0 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts._registry.domain }}</template>
|
||||
<template #value>{{ $ts.system }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts._registry.scope }}</template>
|
||||
<template #value>{{ scope.join('/') }}</template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="keys">
|
||||
<template #label>{{ $ts._registry.keys }}</template>
|
||||
<FormLink v-for="key in keys" :to="`/settings/registry/value/system/${scope.join('/')}/${key[0]}`" class="_monospace">{{ key[0] }}<template #suffix>{{ key[1].toUpperCase() }}</template></FormLink>
|
||||
</FormGroup>
|
||||
|
||||
<FormButton primary @click="createKey">{{ $ts._registry.createKey }}</FormButton>
|
||||
</FormBase>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import * as JSON5 from 'json5';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormSelect,
|
||||
FormSwitch,
|
||||
FormButton,
|
||||
FormLink,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
},
|
||||
|
||||
props: {
|
||||
scope: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.registry,
|
||||
icon: 'fas fa-cogs',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
keys: null,
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
scope() {
|
||||
this.fetch();
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$emit('info', this[symbols.PAGE_INFO]);
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetch() {
|
||||
os.api('i/registry/keys-with-type', {
|
||||
scope: this.scope
|
||||
}).then(keys => {
|
||||
this.keys = Object.entries(keys).sort((a, b) => a[0].localeCompare(b[0]));
|
||||
});
|
||||
},
|
||||
|
||||
async createKey() {
|
||||
const { canceled, result } = await os.form(this.$ts._registry.createKey, {
|
||||
key: {
|
||||
type: 'string',
|
||||
label: this.$ts._registry.key,
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
multiline: true,
|
||||
label: this.$ts.value,
|
||||
},
|
||||
scope: {
|
||||
type: 'string',
|
||||
label: this.$ts._registry.scope,
|
||||
default: this.scope.join('/')
|
||||
}
|
||||
});
|
||||
if (canceled) return;
|
||||
os.apiWithDialog('i/registry/set', {
|
||||
scope: result.scope.split('/'),
|
||||
key: result.key,
|
||||
value: JSON5.parse(result.value),
|
||||
}).then(() => {
|
||||
this.fetch();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@@ -1,147 +0,0 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormInfo warn>{{ $ts.editTheseSettingsMayBreakAccount }}</FormInfo>
|
||||
|
||||
<template v-if="value">
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts._registry.domain }}</template>
|
||||
<template #value>{{ $ts.system }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts._registry.scope }}</template>
|
||||
<template #value>{{ scope.join('/') }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts._registry.key }}</template>
|
||||
<template #value>{{ xKey }}</template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormTextarea v-model="valueForEditor" tall class="_monospace" style="tab-size: 2;">
|
||||
<span>{{ $ts.value }} (JSON)</span>
|
||||
</FormTextarea>
|
||||
<FormButton primary @click="save"><i class="fas fa-save"></i> {{ $ts.save }}</FormButton>
|
||||
</FormGroup>
|
||||
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.updatedAt }}</template>
|
||||
<template #value><MkTime :time="value.updatedAt" mode="detail"/></template>
|
||||
</FormKeyValueView>
|
||||
|
||||
<FormButton danger @click="del"><i class="fas fa-trash"></i> {{ $ts.delete }}</FormButton>
|
||||
</template>
|
||||
</FormBase>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import * as JSON5 from 'json5';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormInfo,
|
||||
FormBase,
|
||||
FormSelect,
|
||||
FormSwitch,
|
||||
FormButton,
|
||||
FormTextarea,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
},
|
||||
|
||||
props: {
|
||||
scope: {
|
||||
required: true
|
||||
},
|
||||
xKey: {
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.registry,
|
||||
icon: 'fas fa-cogs',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
value: null,
|
||||
valueForEditor: null,
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
key() {
|
||||
this.fetch();
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$emit('info', this[symbols.PAGE_INFO]);
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetch() {
|
||||
os.api('i/registry/get-detail', {
|
||||
scope: this.scope,
|
||||
key: this.xKey
|
||||
}).then(value => {
|
||||
this.value = value;
|
||||
this.valueForEditor = JSON5.stringify(this.value.value, null, '\t');
|
||||
});
|
||||
},
|
||||
|
||||
save() {
|
||||
try {
|
||||
JSON5.parse(this.valueForEditor);
|
||||
} catch (e) {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: this.$ts.invalidValue
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
os.confirm({
|
||||
type: 'warning',
|
||||
text: this.$ts.saveConfirm,
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
os.apiWithDialog('i/registry/set', {
|
||||
scope: this.scope,
|
||||
key: this.xKey,
|
||||
value: JSON5.parse(this.valueForEditor)
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
del() {
|
||||
os.confirm({
|
||||
type: 'warning',
|
||||
text: this.$ts.deleteConfirm,
|
||||
}).then(({ canceled }) => {
|
||||
if (canceled) return;
|
||||
os.apiWithDialog('i/registry/remove', {
|
||||
scope: this.scope,
|
||||
key: this.xKey
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@@ -1,90 +0,0 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormGroup v-if="scopes">
|
||||
<template #label>{{ $ts.system }}</template>
|
||||
<FormLink v-for="scope in scopes" :to="`/settings/registry/keys/system/${scope.join('/')}`" class="_monospace">{{ scope.join('/') }}</FormLink>
|
||||
</FormGroup>
|
||||
<FormButton primary @click="createKey">{{ $ts._registry.createKey }}</FormButton>
|
||||
</FormBase>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import * as JSON5 from 'json5';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import * as os from '@/os';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormSelect,
|
||||
FormSwitch,
|
||||
FormButton,
|
||||
FormLink,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.registry,
|
||||
icon: 'fas fa-cogs',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
scopes: null,
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$emit('info', this[symbols.PAGE_INFO]);
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetch() {
|
||||
os.api('i/registry/scopes').then(scopes => {
|
||||
this.scopes = scopes.slice().sort((a, b) => a.join('/').localeCompare(b.join('/')));
|
||||
});
|
||||
},
|
||||
|
||||
async createKey() {
|
||||
const { canceled, result } = await os.form(this.$ts._registry.createKey, {
|
||||
key: {
|
||||
type: 'string',
|
||||
label: this.$ts._registry.key,
|
||||
},
|
||||
value: {
|
||||
type: 'string',
|
||||
multiline: true,
|
||||
label: this.$ts.value,
|
||||
},
|
||||
scope: {
|
||||
type: 'string',
|
||||
label: this.$ts._registry.scope,
|
||||
}
|
||||
});
|
||||
if (canceled) return;
|
||||
os.apiWithDialog('i/registry/set', {
|
||||
scope: result.scope.split('/'),
|
||||
key: result.key,
|
||||
value: JSON5.parse(result.value),
|
||||
}).then(() => {
|
||||
this.fetch();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@@ -40,7 +40,6 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormSlot from '@/components/form/slot.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormPagination from '@/components/form/pagination.vue';
|
||||
@@ -51,7 +50,6 @@ import * as symbols from '@/symbols';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormSection,
|
||||
FormLink,
|
||||
FormButton,
|
||||
FormPagination,
|
||||
FormSlot,
|
||||
|
@@ -1,40 +1,29 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormGroup>
|
||||
<FormTextarea v-model="installThemeCode">
|
||||
<span>{{ $ts._theme.code }}</span>
|
||||
</FormTextarea>
|
||||
<FormButton :disabled="installThemeCode == null" inline @click="() => preview(installThemeCode)"><i class="fas fa-eye"></i> {{ $ts.preview }}</FormButton>
|
||||
</FormGroup>
|
||||
<div class="_formRoot">
|
||||
<FormTextarea v-model="installThemeCode" class="_formBlock">
|
||||
<template #label>{{ $ts._theme.code }}</template>
|
||||
</FormTextarea>
|
||||
|
||||
<FormButton :disabled="installThemeCode == null" primary inline @click="() => install(installThemeCode)"><i class="fas fa-check"></i> {{ $ts.install }}</FormButton>
|
||||
</FormBase>
|
||||
<div class="_formBlock" style="display: flex; gap: var(--margin); flex-wrap: wrap;">
|
||||
<FormButton :disabled="installThemeCode == null" inline @click="() => preview(installThemeCode)"><i class="fas fa-eye"></i> {{ $ts.preview }}</FormButton>
|
||||
<FormButton :disabled="installThemeCode == null" primary inline @click="() => install(installThemeCode)"><i class="fas fa-check"></i> {{ $ts.install }}</FormButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import * as JSON5 from 'json5';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormRadios from '@/components/form/radios.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import { applyTheme, validateTheme } from '@/scripts/theme';
|
||||
import * as os from '@/os';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
import { addTheme, getThemes } from '@/theme-store';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormTextarea,
|
||||
FormSelect,
|
||||
FormRadios,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormLink,
|
||||
FormButton,
|
||||
},
|
||||
|
||||
|
@@ -30,9 +30,6 @@ import { defineComponent } from 'vue';
|
||||
import * as JSON5 from 'json5';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormRadios from '@/components/form/radios.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormInput from '@/components/form/input.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import { Theme, builtinThemes } from '@/scripts/theme';
|
||||
@@ -46,9 +43,6 @@ export default defineComponent({
|
||||
components: {
|
||||
FormTextarea,
|
||||
FormSelect,
|
||||
FormRadios,
|
||||
FormBase,
|
||||
FormGroup,
|
||||
FormInput,
|
||||
FormButton,
|
||||
},
|
||||
|
@@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<template v-if="meta">
|
||||
<FormInfo v-if="version === meta.version">{{ $ts.youAreRunningUpToDateClient }}</FormInfo>
|
||||
<FormInfo v-else warn>{{ $ts.newVersionOfClientAvailable }}</FormInfo>
|
||||
</template>
|
||||
<FormGroup>
|
||||
<template #label>{{ instanceName }}</template>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.currentVersion }}</template>
|
||||
<template #value>{{ version }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.latestVersion }}</template>
|
||||
<template v-if="meta" #value>{{ meta.version }}</template>
|
||||
<template v-else #value><MkEllipsis/></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<template #label>Misskey</template>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.latestVersion }}</template>
|
||||
<template v-if="releases" #value>{{ releases[0].tag_name }}</template>
|
||||
<template v-else #value><MkEllipsis/></template>
|
||||
</FormKeyValueView>
|
||||
<template v-if="releases" #caption><MkTime :time="releases[0].published_at" mode="detail"/></template>
|
||||
</FormGroup>
|
||||
</FormBase>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import FormInfo from '@/components/debobigego/info.vue';
|
||||
import * as os from '@/os';
|
||||
import { version, instanceName } from '@/config';
|
||||
import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormSelect,
|
||||
FormSwitch,
|
||||
FormButton,
|
||||
FormLink,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
FormInfo,
|
||||
},
|
||||
|
||||
emits: ['info'],
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: 'Misskey Update',
|
||||
icon: 'fas fa-sync-alt',
|
||||
bg: 'var(--bg)',
|
||||
},
|
||||
version,
|
||||
instanceName,
|
||||
releases: null,
|
||||
meta: null
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$emit('info', this[symbols.PAGE_INFO]);
|
||||
|
||||
os.api('meta', {
|
||||
detail: false
|
||||
}).then(meta => {
|
||||
this.meta = meta;
|
||||
localStorage.setItem('v', meta.version);
|
||||
});
|
||||
|
||||
fetch('https://api.github.com/repos/misskey-dev/misskey/releases', {
|
||||
method: 'GET',
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
this.releases = res;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
}
|
||||
});
|
||||
</script>
|
@@ -31,7 +31,6 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import MkKeyValue from '@/components/key-value.vue';
|
||||
import MkButton from '@/components/ui/button.vue';
|
||||
import MkInfo from '@/components/ui/info.vue';
|
||||
@@ -42,7 +41,6 @@ import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
MkButton,
|
||||
FormTextarea,
|
||||
MkKeyValue,
|
||||
|
@@ -1,61 +1,67 @@
|
||||
<template>
|
||||
<FormBase class="cwepdizn">
|
||||
<div class="_debobigegoItem colorPicker">
|
||||
<div class="_debobigegoLabel">{{ $ts.backgroundColor }}</div>
|
||||
<div class="_debobigegoPanel colors">
|
||||
<div class="row">
|
||||
<button v-for="color in bgColors.filter(x => x.kind === 'light')" :key="color.color" class="color _button" :class="{ active: theme.props.bg === color.color }" @click="setBgColor(color)">
|
||||
<div class="preview" :style="{ background: color.forPreview }"></div>
|
||||
</button>
|
||||
<MkSpacer :content-max="800" :margin-min="16" :margin-max="32">
|
||||
<div class="cwepdizn _formRoot">
|
||||
<FormFolder :default-open="true" class="_formBlock">
|
||||
<template #label>{{ $ts.backgroundColor }}</template>
|
||||
<div class="cwepdizn-colors">
|
||||
<div class="row">
|
||||
<button v-for="color in bgColors.filter(x => x.kind === 'light')" :key="color.color" class="color _button" :class="{ active: theme.props.bg === color.color }" @click="setBgColor(color)">
|
||||
<div class="preview" :style="{ background: color.forPreview }"></div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button v-for="color in bgColors.filter(x => x.kind === 'dark')" :key="color.color" class="color _button" :class="{ active: theme.props.bg === color.color }" @click="setBgColor(color)">
|
||||
<div class="preview" :style="{ background: color.forPreview }"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<button v-for="color in bgColors.filter(x => x.kind === 'dark')" :key="color.color" class="color _button" :class="{ active: theme.props.bg === color.color }" @click="setBgColor(color)">
|
||||
<div class="preview" :style="{ background: color.forPreview }"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_debobigegoItem colorPicker">
|
||||
<div class="_debobigegoLabel">{{ $ts.accentColor }}</div>
|
||||
<div class="_debobigegoPanel colors">
|
||||
<div class="row">
|
||||
<button v-for="color in accentColors" :key="color" class="color rounded _button" :class="{ active: theme.props.accent === color }" @click="setAccentColor(color)">
|
||||
<div class="preview" :style="{ background: color }"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="_debobigegoItem colorPicker">
|
||||
<div class="_debobigegoLabel">{{ $ts.textColor }}</div>
|
||||
<div class="_debobigegoPanel colors">
|
||||
<div class="row">
|
||||
<button v-for="color in fgColors" :key="color" class="color char _button" :class="{ active: (theme.props.fg === color.forLight) || (theme.props.fg === color.forDark) }" @click="setFgColor(color)">
|
||||
<div class="preview" :style="{ color: color.forPreview ? color.forPreview : theme.base === 'light' ? '#5f5f5f' : '#dadada' }">A</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FormFolder>
|
||||
|
||||
<FormGroup v-if="codeEnabled">
|
||||
<FormTextarea v-model="themeCode" tall>
|
||||
<span>{{ $ts._theme.code }}</span>
|
||||
</FormTextarea>
|
||||
<FormButton primary @click="applyThemeCode">{{ $ts.apply }}</FormButton>
|
||||
</FormGroup>
|
||||
<FormButton v-else @click="codeEnabled = true"><i class="fas fa-code"></i> {{ $ts.editCode }}</FormButton>
|
||||
<FormFolder :default-open="true" class="_formBlock">
|
||||
<template #label>{{ $ts.accentColor }}</template>
|
||||
<div class="cwepdizn-colors">
|
||||
<div class="row">
|
||||
<button v-for="color in accentColors" :key="color" class="color rounded _button" :class="{ active: theme.props.accent === color }" @click="setAccentColor(color)">
|
||||
<div class="preview" :style="{ background: color }"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</FormFolder>
|
||||
|
||||
<FormGroup v-if="descriptionEnabled">
|
||||
<FormTextarea v-model="description">
|
||||
<span>{{ $ts._theme.description }}</span>
|
||||
</FormTextarea>
|
||||
</FormGroup>
|
||||
<FormButton v-else @click="descriptionEnabled = true">{{ $ts.addDescription }}</FormButton>
|
||||
<FormFolder :default-open="true" class="_formBlock">
|
||||
<template #label>{{ $ts.textColor }}</template>
|
||||
<div class="cwepdizn-colors">
|
||||
<div class="row">
|
||||
<button v-for="color in fgColors" :key="color" class="color char _button" :class="{ active: (theme.props.fg === color.forLight) || (theme.props.fg === color.forDark) }" @click="setFgColor(color)">
|
||||
<div class="preview" :style="{ color: color.forPreview ? color.forPreview : theme.base === 'light' ? '#5f5f5f' : '#dadada' }">A</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</FormFolder>
|
||||
|
||||
<FormGroup>
|
||||
<FormButton @click="showPreview"><i class="fas fa-eye"></i> {{ $ts.preview }}</FormButton>
|
||||
<FormButton primary @click="saveAs"><i class="fas fa-save"></i> {{ $ts.saveAs }}</FormButton>
|
||||
</FormGroup>
|
||||
</FormBase>
|
||||
<FormFolder :default-open="false" class="_formBlock">
|
||||
<template #icon><i class="fas fa-code"></i></template>
|
||||
<template #label>{{ $ts.editCode }}</template>
|
||||
|
||||
<div class="_formRoot">
|
||||
<FormTextarea v-model="themeCode" tall class="_formBlock">
|
||||
<template #label>{{ $ts._theme.code }}</template>
|
||||
</FormTextarea>
|
||||
<FormButton primary class="_formBlock" @click="applyThemeCode">{{ $ts.apply }}</FormButton>
|
||||
</div>
|
||||
</FormFolder>
|
||||
|
||||
<FormFolder :default-open="false" class="_formBlock">
|
||||
<template #label>{{ $ts.addDescription }}</template>
|
||||
|
||||
<div class="_formRoot">
|
||||
<FormTextarea v-model="description">
|
||||
<template #label>{{ $ts._theme.description }}</template>
|
||||
</FormTextarea>
|
||||
</div>
|
||||
</FormFolder>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -65,12 +71,11 @@ import * as tinycolor from 'tinycolor2';
|
||||
import { v4 as uuid} from 'uuid';
|
||||
import * as JSON5 from 'json5';
|
||||
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormTextarea from '@/components/debobigego/textarea.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormFolder from '@/components/form/folder.vue';
|
||||
|
||||
import { Theme, applyTheme, validateTheme, darkTheme, lightTheme } from '@/scripts/theme';
|
||||
import { Theme, applyTheme, darkTheme, lightTheme } from '@/scripts/theme';
|
||||
import { host } from '@/config';
|
||||
import * as os from '@/os';
|
||||
import { ColdDeviceStorage } from '@/store';
|
||||
@@ -79,10 +84,9 @@ import * as symbols from '@/symbols';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormButton,
|
||||
FormTextarea,
|
||||
FormGroup,
|
||||
FormFolder,
|
||||
},
|
||||
|
||||
async beforeRouteLeave(to, from) {
|
||||
@@ -96,13 +100,23 @@ export default defineComponent({
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.themeEditor,
|
||||
icon: 'fas fa-palette',
|
||||
bg: 'var(--bg)',
|
||||
actions: [{
|
||||
asFullButton: true,
|
||||
icon: 'fas fa-eye',
|
||||
text: this.$ts.preview,
|
||||
handler: this.showPreview,
|
||||
}, {
|
||||
asFullButton: true,
|
||||
icon: 'fas fa-check',
|
||||
text: this.$ts.saveAs,
|
||||
handler: this.saveAs,
|
||||
}],
|
||||
},
|
||||
theme: {
|
||||
base: 'light',
|
||||
props: lightTheme.props
|
||||
} as Theme,
|
||||
codeEnabled: false,
|
||||
descriptionEnabled: false,
|
||||
description: null,
|
||||
themeCode: null,
|
||||
bgColors: [
|
||||
@@ -244,57 +258,51 @@ export default defineComponent({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cwepdizn {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
::v-deep(.cwepdizn-colors) {
|
||||
text-align: center;
|
||||
|
||||
> .colorPicker {
|
||||
> .colors {
|
||||
padding: 32px;
|
||||
text-align: center;
|
||||
> .row {
|
||||
> .color {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 8px;
|
||||
|
||||
> .row {
|
||||
> .color {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 8px;
|
||||
> .preview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgb(0 0 0 / 30%);
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> .preview {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
box-shadow: 0 0 0 2px var(--divider) inset;
|
||||
}
|
||||
|
||||
&.rounded {
|
||||
border-radius: 999px;
|
||||
|
||||
> .preview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px rgb(0 0 0 / 30%);
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> .preview {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
box-shadow: 0 0 0 2px var(--divider) inset;
|
||||
}
|
||||
|
||||
&.rounded {
|
||||
border-radius: 999px;
|
||||
|
||||
> .preview {
|
||||
border-radius: 999px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.char {
|
||||
line-height: 42px;
|
||||
}
|
||||
&.char {
|
||||
line-height: 42px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,124 +0,0 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<FormSuspense v-slot="{ result: ap }" :p="apPromiseFactory">
|
||||
<FormGroup>
|
||||
<template #label>ActivityPub</template>
|
||||
<FormKeyValueView>
|
||||
<template #key>Type</template>
|
||||
<template #value><span class="_monospace">{{ ap.type }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>URI</template>
|
||||
<template #value><span class="_monospace">{{ ap.id }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>URL</template>
|
||||
<template #value><span class="_monospace">{{ ap.url }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>Inbox</template>
|
||||
<template #value><span class="_monospace">{{ ap.inbox }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>Shared Inbox</template>
|
||||
<template #value><span class="_monospace">{{ ap.sharedInbox || ap.endpoints.sharedInbox }}</span></template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>Outbox</template>
|
||||
<template #value><span class="_monospace">{{ ap.outbox }}</span></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
<FormTextarea readonly tall code pre :value="ap.publicKey.publicKeyPem">
|
||||
<span>Public Key</span>
|
||||
</FormTextarea>
|
||||
<FormKeyValueView>
|
||||
<template #key>Discoverable</template>
|
||||
<template #value>{{ ap.discoverable ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormKeyValueView>
|
||||
<template #key>ManuallyApprovesFollowers</template>
|
||||
<template #value>{{ ap.manuallyApprovesFollowers ? $ts.yes : $ts.no }}</template>
|
||||
</FormKeyValueView>
|
||||
<FormObjectView tall :value="ap">
|
||||
<span>Raw</span>
|
||||
</FormObjectView>
|
||||
<FormGroup>
|
||||
<FormLink :to="`https://${user.host}/.well-known/webfinger?resource=acct:${user.username}`" external>WebFinger</FormLink>
|
||||
</FormGroup>
|
||||
<FormLink v-if="user.host" :to="`/instance-info/${user.host}`">{{ $ts.instanceInfo }}<template #suffix>{{ user.host }}</template></FormLink>
|
||||
<FormKeyValueView v-else>
|
||||
<template #key>{{ $ts.instanceInfo }}</template>
|
||||
<template #value>(Local user)</template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormObjectView from '@/components/debobigego/object-view.vue';
|
||||
import FormTextarea from '@/components/debobigego/textarea.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import number from '@/filters/number';
|
||||
import bytes from '@/filters/bytes';
|
||||
import * as symbols from '@/symbols';
|
||||
import { url } from '@/config';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormTextarea,
|
||||
FormObjectView,
|
||||
FormButton,
|
||||
FormLink,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
FormSuspense,
|
||||
},
|
||||
|
||||
props: {
|
||||
userId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
[symbols.PAGE_INFO]: {
|
||||
title: this.$ts.userInfo,
|
||||
icon: 'fas fa-info-circle'
|
||||
},
|
||||
user: null,
|
||||
apPromiseFactory: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
methods: {
|
||||
number,
|
||||
bytes,
|
||||
|
||||
async fetch() {
|
||||
this.user = await os.api('users/show', {
|
||||
userId: this.userId
|
||||
});
|
||||
|
||||
this.apPromiseFactory = () => os.api('ap/get', {
|
||||
uri: this.user.uri || `${url}/users/${this.user.id}`
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
@@ -1,70 +1,75 @@
|
||||
<template>
|
||||
<FormBase>
|
||||
<MkSpacer :content-max="500" :margin-min="16" :margin-max="32">
|
||||
<FormSuspense :p="init">
|
||||
<div class="_debobigegoItem aeakzknw">
|
||||
<MkAvatar class="avatar" :user="user" :show-indicator="true"/>
|
||||
<div class="_formRoot">
|
||||
<div class="_formBlock aeakzknw">
|
||||
<MkAvatar class="avatar" :user="user" :show-indicator="true"/>
|
||||
</div>
|
||||
|
||||
<FormLink :to="userPage(user)">Profile</FormLink>
|
||||
|
||||
<div class="_formBlock">
|
||||
<MkKeyValue :copy="acct(user)" oneline style="margin: 1em 0;">
|
||||
<template #key>Acct</template>
|
||||
<template #value><span class="_monospace">{{ acct(user) }}</span></template>
|
||||
</MkKeyValue>
|
||||
|
||||
<MkKeyValue :copy="user.id" oneline style="margin: 1em 0;">
|
||||
<template #key>ID</template>
|
||||
<template #value><span class="_monospace">{{ user.id }}</span></template>
|
||||
</MkKeyValue>
|
||||
</div>
|
||||
|
||||
<FormSection v-if="iAmModerator">
|
||||
<template #label>Moderation</template>
|
||||
<FormSwitch v-if="user.host == null && $i.isAdmin && (moderator || !user.isAdmin)" v-model="moderator" class="_formBlock" @update:modelValue="toggleModerator">{{ $ts.moderator }}</FormSwitch>
|
||||
<FormSwitch v-model="silenced" class="_formBlock" @update:modelValue="toggleSilence">{{ $ts.silence }}</FormSwitch>
|
||||
<FormSwitch v-model="suspended" class="_formBlock" @update:modelValue="toggleSuspend">{{ $ts.suspend }}</FormSwitch>
|
||||
<FormButton v-if="user.host == null && iAmModerator" class="_formBlock" @click="resetPassword"><i class="fas fa-key"></i> {{ $ts.resetPassword }}</FormButton>
|
||||
</FormSection>
|
||||
|
||||
<FormSection>
|
||||
<template #label>ActivityPub</template>
|
||||
|
||||
<div class="_formBlock">
|
||||
<MkKeyValue v-if="user.host" oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.instanceInfo }}</template>
|
||||
<template #value><MkA :to="`/instance-info/${user.host}`" class="_link">{{ user.host }} <i class="fas fa-angle-right"></i></MkA></template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue v-else oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.instanceInfo }}</template>
|
||||
<template #value>(Local user)</template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue oneline style="margin: 1em 0;">
|
||||
<template #key>{{ $ts.updatedAt }}</template>
|
||||
<template #value><MkTime v-if="user.lastFetchedAt" mode="detail" :time="user.lastFetchedAt"/><span v-else>N/A</span></template>
|
||||
</MkKeyValue>
|
||||
<MkKeyValue v-if="ap" oneline style="margin: 1em 0;">
|
||||
<template #key>Type</template>
|
||||
<template #value><span class="_monospace">{{ ap.type }}</span></template>
|
||||
</MkKeyValue>
|
||||
</div>
|
||||
|
||||
<FormButton v-if="user.host != null" class="_formBlock" @click="updateRemoteUser"><i class="fas fa-sync"></i> {{ $ts.updateRemoteUser }}</FormButton>
|
||||
</FormSection>
|
||||
|
||||
<MkObjectView tall :value="user">
|
||||
</MkObjectView>
|
||||
</div>
|
||||
|
||||
<FormLink :to="userPage(user)">Profile</FormLink>
|
||||
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>Acct</template>
|
||||
<template #value><span class="_monospace">{{ acct(user) }}</span></template>
|
||||
</FormKeyValueView>
|
||||
|
||||
<FormKeyValueView>
|
||||
<template #key>ID</template>
|
||||
<template #value><span class="_monospace">{{ user.id }}</span></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup v-if="iAmModerator">
|
||||
<FormSwitch v-if="user.host == null && $i.isAdmin && (moderator || !user.isAdmin)" v-model="moderator" @update:modelValue="toggleModerator">{{ $ts.moderator }}</FormSwitch>
|
||||
<FormSwitch v-model="silenced" @update:modelValue="toggleSilence">{{ $ts.silence }}</FormSwitch>
|
||||
<FormSwitch v-model="suspended" @update:modelValue="toggleSuspend">{{ $ts.suspend }}</FormSwitch>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormButton v-if="user.host != null" @click="updateRemoteUser"><i class="fas fa-sync"></i> {{ $ts.updateRemoteUser }}</FormButton>
|
||||
<FormButton v-if="user.host == null && iAmModerator" @click="resetPassword"><i class="fas fa-key"></i> {{ $ts.resetPassword }}</FormButton>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLink :to="`/user-ap-info/${user.id}`">ActivityPub</FormLink>
|
||||
|
||||
<FormLink v-if="user.host" :to="`/instance-info/${user.host}`">{{ $ts.instanceInfo }}<template #suffix>{{ user.host }}</template></FormLink>
|
||||
<FormKeyValueView v-else>
|
||||
<template #key>{{ $ts.instanceInfo }}</template>
|
||||
<template #value>(Local user)</template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormKeyValueView>
|
||||
<template #key>{{ $ts.updatedAt }}</template>
|
||||
<template #value><MkTime v-if="user.lastFetchedAt" mode="detail" :time="user.lastFetchedAt"/><span v-else>N/A</span></template>
|
||||
</FormKeyValueView>
|
||||
</FormGroup>
|
||||
|
||||
<FormObjectView tall :value="user">
|
||||
<span>Raw</span>
|
||||
</FormObjectView>
|
||||
</FormSuspense>
|
||||
</FormBase>
|
||||
</MkSpacer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineAsyncComponent, defineComponent } from 'vue';
|
||||
import FormObjectView from '@/components/debobigego/object-view.vue';
|
||||
import FormTextarea from '@/components/debobigego/textarea.vue';
|
||||
import FormSwitch from '@/components/debobigego/switch.vue';
|
||||
import FormLink from '@/components/debobigego/link.vue';
|
||||
import FormBase from '@/components/debobigego/base.vue';
|
||||
import FormGroup from '@/components/debobigego/group.vue';
|
||||
import FormButton from '@/components/debobigego/button.vue';
|
||||
import FormKeyValueView from '@/components/debobigego/key-value-view.vue';
|
||||
import FormSuspense from '@/components/debobigego/suspense.vue';
|
||||
import MkObjectView from '@/components/object-view.vue';
|
||||
import FormTextarea from '@/components/form/textarea.vue';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import FormSection from '@/components/form/section.vue';
|
||||
import FormButton from '@/components/ui/button.vue';
|
||||
import MkKeyValue from '@/components/key-value.vue';
|
||||
import FormSuspense from '@/components/form/suspense.vue';
|
||||
import * as os from '@/os';
|
||||
import number from '@/filters/number';
|
||||
import bytes from '@/filters/bytes';
|
||||
@@ -74,14 +79,13 @@ import { userPage, acct } from '@/filters/user';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
FormBase,
|
||||
FormSection,
|
||||
FormTextarea,
|
||||
FormSwitch,
|
||||
FormObjectView,
|
||||
MkObjectView,
|
||||
FormButton,
|
||||
FormLink,
|
||||
FormGroup,
|
||||
FormKeyValueView,
|
||||
MkKeyValue,
|
||||
FormSuspense,
|
||||
},
|
||||
|
||||
@@ -97,6 +101,7 @@ export default defineComponent({
|
||||
[symbols.PAGE_INFO]: computed(() => ({
|
||||
title: this.user ? acct(this.user) : this.$ts.userInfo,
|
||||
icon: 'fas fa-info-circle',
|
||||
bg: 'var(--bg)',
|
||||
actions: this.user ? [this.user.url ? {
|
||||
text: this.user.url,
|
||||
icon: 'fas fa-external-link-alt',
|
||||
@@ -108,6 +113,7 @@ export default defineComponent({
|
||||
init: null,
|
||||
user: null,
|
||||
info: null,
|
||||
ap: null,
|
||||
moderator: false,
|
||||
silenced: false,
|
||||
suspended: false,
|
||||
@@ -126,6 +132,13 @@ export default defineComponent({
|
||||
this.init = this.createFetcher();
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
user() {
|
||||
os.api('ap/get', {
|
||||
uri: this.user.uri || `${url}/users/${this.user.id}`
|
||||
}).then(res => {
|
||||
this.ap = res;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -234,7 +247,6 @@ export default defineComponent({
|
||||
.aeakzknw {
|
||||
> .avatar {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
@@ -73,7 +73,6 @@ const defaultRoutes = [
|
||||
{ path: '/notes/:note', name: 'note', component: page('note'), props: route => ({ noteId: route.params.note }) },
|
||||
{ path: '/tags/:tag', component: page('tag'), props: route => ({ tag: route.params.tag }) },
|
||||
{ path: '/user-info/:user', component: page('user-info'), props: route => ({ userId: route.params.user }) },
|
||||
{ path: '/user-ap-info/:user', component: page('user-ap-info'), props: route => ({ userId: route.params.user }) },
|
||||
{ path: '/instance-info/:host', component: page('instance-info'), props: route => ({ host: route.params.host }) },
|
||||
{ path: '/games/reversi', component: page('reversi/index') },
|
||||
{ path: '/games/reversi/:gameId', component: page('reversi/game'), props: route => ({ gameId: route.params.gameId }) },
|
||||
|
@@ -69,6 +69,9 @@
|
||||
success: '#86b300',
|
||||
error: '#ec4137',
|
||||
warn: '#ecb637',
|
||||
codeString: '#ffb675',
|
||||
codeNumber: '#cfff9e',
|
||||
codeBoolean: '#c59eff',
|
||||
htmlThemeColor: '@bg',
|
||||
X2: ':darken<2<@panel',
|
||||
X3: 'rgba(255, 255, 255, 0.05)',
|
||||
|
@@ -69,6 +69,9 @@
|
||||
success: '#86b300',
|
||||
error: '#ec4137',
|
||||
warn: '#ecb637',
|
||||
codeString: '#b98710',
|
||||
codeNumber: '#0fbbbb',
|
||||
codeBoolean: '#62b70c',
|
||||
htmlThemeColor: '@bg',
|
||||
X2: ':darken<2<@panel',
|
||||
X3: 'rgba(0, 0, 0, 0.05)',
|
||||
|
Reference in New Issue
Block a user