mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 15:34:13 +00:00 
			
		
		
		
	Resolve #6500
This commit is contained in:
		
							parent
							
								
									ade11aa447
								
							
						
					
					
						commit
						c25cf7f89a
					
				
					 4 changed files with 90 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -87,8 +87,9 @@
 | 
			
		|||
		</main>
 | 
			
		||||
 | 
			
		||||
		<template v-if="isDesktop">
 | 
			
		||||
			<div class="widgets" :class="{ edit: widgetsEditMode, fixed: $store.state.device.fixedWidgetsPosition }" v-for="place in ['left', 'right']" :key="place">
 | 
			
		||||
				<template v-if="widgetsEditMode">
 | 
			
		||||
			<div v-for="place in ['left', 'right']" ref="widgets" class="widgets" :class="{ edit: widgetsEditMode, fixed: $store.state.device.fixedWidgetsPosition, empty: widgets[place].length === 0 && !widgetsEditMode }" :key="place">
 | 
			
		||||
				<div class="spacer"></div>
 | 
			
		||||
				<div class="container" v-if="widgetsEditMode">
 | 
			
		||||
					<mk-button primary @click="addWidget(place)" class="add"><fa :icon="faPlus"/></mk-button>
 | 
			
		||||
					<x-draggable
 | 
			
		||||
						:list="widgets[place]"
 | 
			
		||||
| 
						 | 
				
			
			@ -106,8 +107,10 @@
 | 
			
		|||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
					</x-draggable>
 | 
			
		||||
				</template>
 | 
			
		||||
				<component v-else class="_widget" v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget"/>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="container" v-else>
 | 
			
		||||
					<component class="_widget" v-for="widget in widgets[place]" :is="`mkw-${widget.name}`" :key="widget.id" :ref="widget.id" :widget="widget"/>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</template>
 | 
			
		||||
	</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +137,7 @@ import { ResizeObserver } from '@juggle/resize-observer';
 | 
			
		|||
import { v4 as uuid } from 'uuid';
 | 
			
		||||
import { host, instanceName } from './config';
 | 
			
		||||
import { search } from './scripts/search';
 | 
			
		||||
import { StickySidebar } from './scripts/sticky-sidebar';
 | 
			
		||||
 | 
			
		||||
const DESKTOP_THRESHOLD = 1100;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -232,6 +236,12 @@ export default Vue.extend({
 | 
			
		|||
			this.showNav = false;
 | 
			
		||||
			this.canBack = (window.history.length > 0 && !['index'].includes(to.name));
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		isDesktop() {
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.attachSticky();
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
| 
						 | 
				
			
			@ -277,9 +287,24 @@ export default Vue.extend({
 | 
			
		|||
				if (window.innerWidth >= DESKTOP_THRESHOLD) this.isDesktop = true;
 | 
			
		||||
			}, { passive: true });
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// widget follow
 | 
			
		||||
		this.attachSticky();
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		attachSticky() {
 | 
			
		||||
			if (!this.isDesktop) return;
 | 
			
		||||
			if (this.$store.state.device.fixedWidgetsPosition) return;
 | 
			
		||||
 | 
			
		||||
			const stickyWidgetColumns = this.$refs.widgets.map(w => new StickySidebar(w.children[1], w.children[0], w.offsetTop));
 | 
			
		||||
			window.addEventListener('scroll', () => {
 | 
			
		||||
				for (const stickyWidgetColumn of stickyWidgetColumns) {
 | 
			
		||||
					stickyWidgetColumn.calc(window.scrollY);
 | 
			
		||||
				}
 | 
			
		||||
			}, { passive: true });
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		top() {
 | 
			
		||||
			window.scroll({ top: 0, behavior: 'smooth' });
 | 
			
		||||
		},
 | 
			
		||||
| 
						 | 
				
			
			@ -988,15 +1013,14 @@ export default Vue.extend({
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		> .widgets {
 | 
			
		||||
			top: $header-height;
 | 
			
		||||
			min-height: calc(100vh - #{$header-height});
 | 
			
		||||
			padding: 0 var(--margin);
 | 
			
		||||
			box-shadow: 1px 0 0 0 var(--divider), -1px 0 0 0 var(--divider);
 | 
			
		||||
 | 
			
		||||
			&.fixed {
 | 
			
		||||
				position: sticky;
 | 
			
		||||
				height: calc(100vh - #{$header-height});
 | 
			
		||||
				overflow: auto;
 | 
			
		||||
				height: calc(100vh - #{$header-height});
 | 
			
		||||
				top: $header-height;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			&:first-of-type {
 | 
			
		||||
| 
						 | 
				
			
			@ -1007,7 +1031,7 @@ export default Vue.extend({
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			&:empty {
 | 
			
		||||
			&.empty {
 | 
			
		||||
				display: none;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1015,9 +1039,16 @@ export default Vue.extend({
 | 
			
		|||
				display: none;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			> * {
 | 
			
		||||
				margin: var(--margin) 0;
 | 
			
		||||
				width: 300px;
 | 
			
		||||
			> .container {
 | 
			
		||||
				position: sticky;
 | 
			
		||||
				height: min-content;
 | 
			
		||||
				min-height: calc(100vh - #{$header-height});
 | 
			
		||||
				overflow: hidden;
 | 
			
		||||
 | 
			
		||||
				> * {
 | 
			
		||||
					margin: var(--margin) 0;
 | 
			
		||||
					width: 300px;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			> .add {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -265,6 +265,10 @@ export default Vue.extend({
 | 
			
		|||
			}
 | 
			
		||||
			location.reload();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		fixedWidgetsPosition() {
 | 
			
		||||
			location.reload()
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										43
									
								
								src/client/scripts/sticky-sidebar.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/client/scripts/sticky-sidebar.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
export class StickySidebar {
 | 
			
		||||
	private lastScrollTop = 0;
 | 
			
		||||
	private el: HTMLElement;
 | 
			
		||||
	private spacer: HTMLElement;
 | 
			
		||||
	private marginTop: number;
 | 
			
		||||
	private isTop = false;
 | 
			
		||||
	private isBottom = false;
 | 
			
		||||
 | 
			
		||||
	constructor(el: StickySidebar['el'], spacer: StickySidebar['spacer'], marginTop = 0) {
 | 
			
		||||
		this.el = el;
 | 
			
		||||
		this.spacer = spacer;
 | 
			
		||||
		this.marginTop = marginTop;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public calc(scrollTop: number) {
 | 
			
		||||
		if (scrollTop > this.lastScrollTop) { // downscroll
 | 
			
		||||
			const overflow = this.el.clientHeight - window.innerHeight;
 | 
			
		||||
			this.el.style.bottom = null;
 | 
			
		||||
			this.el.style.top = `${-overflow}px`;
 | 
			
		||||
 | 
			
		||||
			this.isBottom = (scrollTop + window.innerHeight) >= (this.el.offsetTop + this.el.clientHeight);
 | 
			
		||||
 | 
			
		||||
			if (this.isTop) {
 | 
			
		||||
				this.isTop = false;
 | 
			
		||||
				this.spacer.style.marginTop = `${scrollTop}px`;
 | 
			
		||||
			}
 | 
			
		||||
		} else { // upscroll
 | 
			
		||||
			const overflow = this.el.clientHeight - window.innerHeight;
 | 
			
		||||
			this.el.style.top = null;
 | 
			
		||||
			this.el.style.bottom = `${-overflow - this.marginTop}px`;
 | 
			
		||||
 | 
			
		||||
			this.isTop = scrollTop <= this.el.offsetTop;
 | 
			
		||||
 | 
			
		||||
			if (this.isBottom) {
 | 
			
		||||
				this.isBottom = false;
 | 
			
		||||
				const overflow = this.el.clientHeight - window.innerHeight;
 | 
			
		||||
				this.spacer.style.marginTop = `${scrollTop - (overflow + this.marginTop)}px`;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.lastScrollTop = scrollTop <= 0 ? 0 : scrollTop;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ export const defaultDeviceSettings = {
 | 
			
		|||
	showFixedPostForm: false,
 | 
			
		||||
	disablePagesScript: true,
 | 
			
		||||
	enableInfiniteScroll: true,
 | 
			
		||||
	fixedWidgetsPosition: true,
 | 
			
		||||
	fixedWidgetsPosition: false,
 | 
			
		||||
	roomGraphicsQuality: 'medium',
 | 
			
		||||
	roomUseOrthographicCamera: true,
 | 
			
		||||
	sfxVolume: 0.3,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue