Better widgets
This commit is contained in:
		
							parent
							
								
									514eb39a14
								
							
						
					
					
						commit
						5268bade66
					
				
					 2 changed files with 60 additions and 45 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue