Better widgets

This commit is contained in:
syuilo 2020-02-10 05:42:03 +09:00
parent 514eb39a14
commit 5268bade66
2 changed files with 60 additions and 45 deletions
locales
src/client

View file

@ -219,8 +219,6 @@ messaging: "チャット"
upload: "アップロード" upload: "アップロード"
fromDrive: "ドライブから" fromDrive: "ドライブから"
fromUrl: "URLから" fromUrl: "URLから"
editWidgets: "ウィジェットを編集"
exitEdit: "編集を終了"
explore: "みつける" explore: "みつける"
games: "Misskey Games" games: "Misskey Games"
messageRead: "既読" messageRead: "既読"

View file

@ -18,8 +18,12 @@
</transition> </transition>
</div> </div>
<div class="sub"> <div class="sub">
<button v-if="widgetsEditMode" class="_button edit active" @click="widgetsEditMode = false"><fa :icon="faGripVertical"/></button>
<button v-else class="_button edit" @click="widgetsEditMode = true"><fa :icon="faGripVertical"/></button>
<div class="search">
<fa :icon="faSearch"/> <fa :icon="faSearch"/>
<input type="search" class="search" :placeholder="$t('search')" v-model="searchQuery" v-autocomplete="{ model: 'searchQuery' }" :disabled="searchWait" @keypress="searchKeypress"/> <input type="search" :placeholder="$t('search')" v-model="searchQuery" v-autocomplete="{ model: 'searchQuery' }" :disabled="searchWait" @keypress="searchKeypress"/>
</div>
<button v-if="$store.getters.isSignedIn" class="post _buttonPrimary" @click="post()"><fa :icon="faPencilAlt"/></button> <button v-if="$store.getters.isSignedIn" class="post _buttonPrimary" @click="post()"><fa :icon="faPencilAlt"/></button>
</div> </div>
</header> </header>
@ -86,7 +90,7 @@
</nav> </nav>
</transition> </transition>
<div class="contents"> <div class="contents" ref="contents">
<main ref="main"> <main ref="main">
<div class="content"> <div class="content">
<transition :name="$store.state.device.animation ? 'page' : ''" mode="out-in" @enter="onTransition"> <transition :name="$store.state.device.animation ? 'page' : ''" mode="out-in" @enter="onTransition">
@ -126,8 +130,6 @@
<template v-else> <template v-else>
<component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget"/> <component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget"/>
</template> </template>
<button ref="widgetsEditButton" v-if="widgetsEditMode" class="_button edit" @click="widgetsEditMode = false">{{ $t('exitEdit') }}</button>
<button ref="widgetsEditButton" v-else class="_button edit" @click="widgetsEditMode = true">{{ $t('editWidgets') }}</button>
</template> </template>
</div> </div>
</div> </div>
@ -150,8 +152,9 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue'; import Vue from 'vue';
import { faChevronLeft, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faListUl, faPlus, faUserClock, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faGamepad, faServer, faFileAlt, faSatellite, faInfoCircle, faQuestionCircle } from '@fortawesome/free-solid-svg-icons'; import { faGripVertical, faChevronLeft, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faListUl, faPlus, faUserClock, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faGamepad, faServer, faFileAlt, faSatellite, faInfoCircle, faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
import { faBell, faEnvelope, faLaugh, faComments } from '@fortawesome/free-regular-svg-icons'; import { faBell, faEnvelope, faLaugh, faComments } from '@fortawesome/free-regular-svg-icons';
import { ResizeObserver } from '@juggle/resize-observer';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import i18n from './i18n'; import i18n from './i18n';
import { host } from './config'; import { host } from './config';
@ -184,7 +187,7 @@ export default Vue.extend({
enableWidgets: window.innerWidth >= 1100, enableWidgets: window.innerWidth >= 1100,
canBack: false, canBack: false,
disconnectedDialog: null as Promise<void> | null, disconnectedDialog: null as Promise<void> | null,
faChevronLeft, faComments, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faBell, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faEnvelope, faListUl, faPlus, faUserClock, faLaugh, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer faGripVertical, faChevronLeft, faComments, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faBell, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faEnvelope, faListUl, faPlus, faUserClock, faLaugh, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer
}; };
}, },
@ -256,25 +259,33 @@ export default Vue.extend({
}); });
} }
}); });
// https://stackoverflow.com/questions/33891709/when-flexbox-items-wrap-in-column-mode-container-does-not-grow-its-width
if (this.enableWidgets) {
setInterval(() => {
if (!this.$refs.widgetsEditButton) return;
const width = this.$refs.widgetsEditButton.offsetLeft + 300;
this.$refs.widgets.style.width = width + 'px';
}, 1000);
}
}, },
mounted() { mounted() {
// https://stackoverflow.com/questions/33891709/when-flexbox-items-wrap-in-column-mode-container-does-not-grow-its-width
if (this.enableWidgets) {
const adjustWidgetsWidth = () => {
const lastChild = this.$refs.widgets.children[this.$refs.widgets.children.length - 1];
if (lastChild == null) return;
const width = lastChild.offsetLeft + 300;
this.$refs.widgets.style.width = width + 'px';
};
setInterval(adjustWidgetsWidth, 1000);
}
const adjustTitlePosition = () => { const adjustTitlePosition = () => {
this.$refs.title.style.left = (this.$refs.main.getBoundingClientRect().left - this.$refs.nav.offsetWidth) + 'px'; this.$refs.title.style.left = (this.$refs.main.getBoundingClientRect().left - this.$refs.nav.offsetWidth) + 'px';
}; };
adjustTitlePosition(); adjustTitlePosition();
const ro = new ResizeObserver((entries, observer) => {
adjustTitlePosition();
});
ro.observe(this.$refs.contents);
window.addEventListener('resize', adjustTitlePosition); window.addEventListener('resize', adjustTitlePosition);
}, },
@ -714,18 +725,20 @@ export default Vue.extend({
display: none; display: none;
} }
> [data-icon] { > .edit {
position: absolute; padding: 16px;
top: 0;
left: 16px; &.active {
height: $header-height; color: var(--accent);
pointer-events: none; }
font-size: 16px;
} }
> .search { > .search {
position: relative;
> input {
$margin: 8px; $margin: 8px;
width: calc(100% - #{$post-button-size + $post-button-margin + $margin}); width: 200px;
box-sizing: border-box; box-sizing: border-box;
margin-right: $margin; margin-right: $margin;
padding: 0 12px 0 42px; padding: 0 12px 0 42px;
@ -741,6 +754,16 @@ export default Vue.extend({
} }
} }
> [data-icon] {
position: absolute;
top: 0;
left: 16px;
height: 100%;
pointer-events: none;
font-size: 16px;
}
}
> .post { > .post {
width: $post-button-size; width: $post-button-size;
height: $post-button-size; height: $post-button-size;
@ -976,12 +999,6 @@ export default Vue.extend({
margin: 0 auto; margin: 0 auto;
} }
> .edit {
display: block;
font-size: 0.9em;
margin: 0 auto;
}
.customize-container { .customize-container {
margin: 8px 0; margin: 8px 0;
background: #fff; background: #fff;