diff --git a/index.html b/index.html
index b8c11f2..50b615b 100644
--- a/index.html
+++ b/index.html
@@ -108,6 +108,7 @@
locationChunk: 'Chunk',
contextMenuCopyLink: 'Copy link to here',
contextMenuCenterHere: 'Center here',
+ toggleTitle: 'Click to toggle this section',
}
};
diff --git a/src/api.ts b/src/api.ts
index d381c38..fb28bad 100644
--- a/src/api.ts
+++ b/src/api.ts
@@ -95,6 +95,7 @@ function buildMessagesConfig(response: any): LiveAtlasMessageConfig {
locationChunk: liveAtlasMessages.locationChunk || '',
contextMenuCopyLink: liveAtlasMessages.contextMenuCopyLink || '',
contextMenuCenterHere: liveAtlasMessages.contextMenuCenterHere || '',
+ toggleTitle: liveAtlasMessages.toggleTitle || '',
}
}
diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue
index 0d9bf65..ba2d1ad 100644
--- a/src/components/Sidebar.vue
+++ b/src/components/Sidebar.vue
@@ -42,9 +42,9 @@ import FollowTarget from './sidebar/FollowTarget.vue';
import {useStore} from "@/store";
import SvgIcon from "@/components/SvgIcon.vue";
import {MutationTypes} from "@/store/mutation-types";
-import {DynmapUIElement} from "@/dynmap";
import "@/assets/icons/players.svg";
import "@/assets/icons/maps.svg";
+import {LiveAtlasUIElement} from "@/index";
export default defineComponent({
components: {
@@ -67,7 +67,7 @@ export default defineComponent({
messageWorlds = computed(() => store.state.messages.worldsHeading),
messagePlayers = computed(() => store.state.messages.playersHeading),
- toggleElement = (element: DynmapUIElement) => {
+ toggleElement = (element: LiveAtlasUIElement) => {
store.commit(MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY, element);
},
@@ -168,7 +168,18 @@ export default defineComponent({
.section__heading {
font-size: 2rem;
- margin-bottom: 1rem;
+ cursor: pointer;
+ user-select: none;
+ padding: 1.5rem 1.5rem 1rem;
+ margin: -1.5rem -1.5rem 0;
+ background-color: transparent;
+ color: inherit;
+ text-align: left;
+
+ &:hover, &:focus-visible, &.focus-visible, &:active {
+ background-color: transparent;
+ color: inherit;
+ }
}
.section__content {
@@ -191,6 +202,17 @@ export default defineComponent({
align-self: center;
margin-top: 1rem;
}
+
+ &.section--collapsed {
+ .section__heading {
+ padding-bottom: 1.5rem;
+ margin-bottom: -1.5rem;
+ }
+
+ .section__content {
+ display: none;
+ }
+ }
}
@media (max-width: 480px) {
diff --git a/src/components/sidebar/CollapsibleSection.vue b/src/components/sidebar/CollapsibleSection.vue
new file mode 100644
index 0000000..621b664
--- /dev/null
+++ b/src/components/sidebar/CollapsibleSection.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
diff --git a/src/components/sidebar/PlayerList.vue b/src/components/sidebar/PlayerList.vue
index 720ecf8..1badb06 100644
--- a/src/components/sidebar/PlayerList.vue
+++ b/src/components/sidebar/PlayerList.vue
@@ -15,22 +15,26 @@
-->
-
+
+ {{ heading }} [{{ players.size }}/{{ maxPlayers }}]
+
+
+
+
diff --git a/src/components/sidebar/ServerList.vue b/src/components/sidebar/ServerList.vue
index e6edf12..f25c707 100644
--- a/src/components/sidebar/ServerList.vue
+++ b/src/components/sidebar/ServerList.vue
@@ -15,22 +15,26 @@
-->
-
+
+ {{ heading }}
+
+
+
+
diff --git a/src/components/sidebar/WorldList.vue b/src/components/sidebar/WorldList.vue
index 5b95c5d..f69fa3d 100644
--- a/src/components/sidebar/WorldList.vue
+++ b/src/components/sidebar/WorldList.vue
@@ -15,23 +15,27 @@
-->
-
+
+ {{ heading }}
+
+
+
+ - {{ skeletonWorlds }}
+
+
+
-
-
\ No newline at end of file
diff --git a/src/dynmap.d.ts b/src/dynmap.d.ts
index 59e319a..cc31e3f 100644
--- a/src/dynmap.d.ts
+++ b/src/dynmap.d.ts
@@ -296,5 +296,3 @@ interface DynmapChat {
source?: string;
timestamp: number;
}
-
-export type DynmapUIElement = 'chat' | 'players' | 'maps' | 'settings';
\ No newline at end of file
diff --git a/src/index.d.ts b/src/index.d.ts
index 4df8dab..ea9f5bc 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -63,4 +63,8 @@ interface LiveAtlasMessageConfig {
locationChunk: string;
contextMenuCopyLink: string;
contextMenuCenterHere: string;
-}
\ No newline at end of file
+ toggleTitle: string;
+}
+
+export type LiveAtlasUIElement = 'chat' | 'players' | 'maps' | 'settings';
+export type LiveAtlasSidebarSection = 'servers' | 'players' | 'maps';
\ No newline at end of file
diff --git a/src/store/mutations.ts b/src/store/mutations.ts
index a09a700..41ce86e 100644
--- a/src/store/mutations.ts
+++ b/src/store/mutations.ts
@@ -28,10 +28,10 @@ import {
DynmapPlayer,
DynmapServerConfig, DynmapTileUpdate,
DynmapWorld,
- DynmapWorldState, DynmapParsedUrl, DynmapChat, DynmapUIElement
+ DynmapWorldState, DynmapParsedUrl, DynmapChat
} from "@/dynmap";
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
-import {LiveAtlasMessageConfig, LiveAtlasServerDefinition} from "@/index";
+import {LiveAtlasMessageConfig, LiveAtlasServerDefinition, LiveAtlasUIElement} from "@/index";
export type CurrentMapPayload = {
worldName: string;
@@ -80,8 +80,8 @@ export type Mutations = {
[MutationTypes.CLEAR_PAN_TARGET](state: S, a?: void): void
[MutationTypes.SET_SMALL_SCREEN](state: S, payload: boolean): void
- [MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY](state: S, payload: DynmapUIElement): void
- [MutationTypes.SET_UI_ELEMENT_VISIBILITY](state: S, payload: {element: DynmapUIElement, state: boolean}): void
+ [MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY](state: S, payload: LiveAtlasUIElement): void
+ [MutationTypes.SET_UI_ELEMENT_VISIBILITY](state: S, payload: {element: LiveAtlasUIElement, state: boolean}): void
[MutationTypes.SET_LOGGED_IN](state: S, payload: boolean): void
}
@@ -509,7 +509,7 @@ export const mutations: MutationTree & Mutations = {
state.ui.smallScreen = smallScreen;
},
- [MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY](state: State, element: DynmapUIElement): void {
+ [MutationTypes.TOGGLE_UI_ELEMENT_VISIBILITY](state: State, element: LiveAtlasUIElement): void {
const newState = !state.ui.visibleElements.has(element);
if(newState && state.ui.smallScreen) {
@@ -520,7 +520,7 @@ export const mutations: MutationTree & Mutations = {
newState ? state.ui.visibleElements.add(element) : state.ui.visibleElements.delete(element);
},
- [MutationTypes.SET_UI_ELEMENT_VISIBILITY](state: State, payload: {element: DynmapUIElement, state: boolean}): void {
+ [MutationTypes.SET_UI_ELEMENT_VISIBILITY](state: State, payload: {element: LiveAtlasUIElement, state: boolean}): void {
if(payload.state && state.ui.smallScreen) {
state.ui.visibleElements.clear();
}
diff --git a/src/store/state.ts b/src/store/state.ts
index 5a60a4a..5365c6c 100644
--- a/src/store/state.ts
+++ b/src/store/state.ts
@@ -19,10 +19,10 @@ import {
DynmapWorldMap, DynmapMarkerSet, DynmapMarkerSetUpdates,
DynmapPlayer,
DynmapServerConfig, DynmapTileUpdate,
- DynmapWorld, DynmapWorldState, Coordinate, DynmapParsedUrl, DynmapChat, DynmapUIElement
+ DynmapWorld, DynmapWorldState, Coordinate, DynmapParsedUrl, DynmapChat
} from "@/dynmap";
import {DynmapProjection} from "@/leaflet/projection/DynmapProjection";
-import {LiveAtlasMessageConfig, LiveAtlasServerDefinition} from "@/index";
+import {LiveAtlasMessageConfig, LiveAtlasServerDefinition, LiveAtlasSidebarSection, LiveAtlasUIElement} from "@/index";
export type State = {
version: string;
@@ -63,8 +63,9 @@ export type State = {
ui: {
smallScreen: boolean;
- visibleElements: Set;
- previouslyVisibleElements: Set;
+ visibleElements: Set;
+ previouslyVisibleElements: Set;
+ collapsedSections: Set;
};
parsedUrl: DynmapParsedUrl;
@@ -125,7 +126,8 @@ export const state: State = {
locationRegion: '',
locationChunk: '',
contextMenuCopyLink: '',
- contextMenuCenterHere: ''
+ contextMenuCenterHere: '',
+ toggleTitle: '',
},
loggedIn: false,
@@ -207,6 +209,7 @@ export const state: State = {
smallScreen: false,
visibleElements:new Set(),
previouslyVisibleElements: new Set(),
+ collapsedSections: new Set(),
},
parsedUrl: {