diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index d665f756c1..258b82dea9 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -219,8 +219,6 @@ messaging: "チャット" upload: "アップロード" fromDrive: "ドライブから" fromUrl: "URLから" -editWidgets: "ウィジェットを編集" -exitEdit: "編集を終了" explore: "みつける" games: "Misskey Games" messageRead: "既読" diff --git a/src/client/app.vue b/src/client/app.vue index 22a56eb1f9..31c7543f36 100644 --- a/src/client/app.vue +++ b/src/client/app.vue @@ -18,8 +18,12 @@ </transition> </div> <div class="sub"> - <fa :icon="faSearch"/> - <input type="search" class="search" :placeholder="$t('search')" v-model="searchQuery" v-autocomplete="{ model: 'searchQuery' }" :disabled="searchWait" @keypress="searchKeypress"/> + <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"/> + <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> </div> </header> @@ -86,7 +90,7 @@ </nav> </transition> - <div class="contents"> + <div class="contents" ref="contents"> <main ref="main"> <div class="content"> <transition :name="$store.state.device.animation ? 'page' : ''" mode="out-in" @enter="onTransition"> @@ -126,8 +130,6 @@ <template v-else> <component class="widget" v-for="widget in widgets" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget"/> </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> </div> </div> @@ -150,8 +152,9 @@ <script lang="ts"> 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 { ResizeObserver } from '@juggle/resize-observer'; import { v4 as uuid } from 'uuid'; import i18n from './i18n'; import { host } from './config'; @@ -184,7 +187,7 @@ export default Vue.extend({ enableWidgets: window.innerWidth >= 1100, canBack: false, 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() { + // 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 = () => { this.$refs.title.style.left = (this.$refs.main.getBoundingClientRect().left - this.$refs.nav.offsetWidth) + 'px'; }; adjustTitlePosition(); + const ro = new ResizeObserver((entries, observer) => { + adjustTitlePosition(); + }); + + ro.observe(this.$refs.contents); + window.addEventListener('resize', adjustTitlePosition); }, @@ -714,30 +725,42 @@ export default Vue.extend({ display: none; } - > [data-icon] { - position: absolute; - top: 0; - left: 16px; - height: $header-height; - pointer-events: none; - font-size: 16px; + > .edit { + padding: 16px; + + &.active { + color: var(--accent); + } } > .search { - $margin: 8px; - width: calc(100% - #{$post-button-size + $post-button-margin + $margin}); - box-sizing: border-box; - margin-right: $margin; - padding: 0 12px 0 42px; - font-size: 1rem; - line-height: 38px; - border: none; - border-radius: 38px; - color: var(--fg); - background: var(--bg); + position: relative; - &:focus { - outline: none; + > input { + $margin: 8px; + width: 200px; + box-sizing: border-box; + margin-right: $margin; + padding: 0 12px 0 42px; + font-size: 1rem; + line-height: 38px; + border: none; + border-radius: 38px; + color: var(--fg); + background: var(--bg); + + &:focus { + outline: none; + } + } + + > [data-icon] { + position: absolute; + top: 0; + left: 16px; + height: 100%; + pointer-events: none; + font-size: 16px; } } @@ -976,12 +999,6 @@ export default Vue.extend({ margin: 0 auto; } - > .edit { - display: block; - font-size: 0.9em; - margin: 0 auto; - } - .customize-container { margin: 8px 0; background: #fff;