feeds-fun 1.18.0 → 1.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feeds-fun",
3
- "version": "1.18.0",
3
+ "version": "1.18.1",
4
4
  "author": "Aliaksei Yaletski (Tiendil) <a.eletsky@gmail.com> (https://tiendil.org/)",
5
5
  "description": "Frontend for the Feeds Fun — web-based news reader",
6
6
  "keywords": [
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <a
3
+ href="#"
4
+ class="ffun-page-header-link text-2xl align-middle flex-none pb-0 relative"
5
+ :title="title"
6
+ @click.prevent="onClick">
7
+ <i
8
+ v-if="globalSettings.showSidebar"
9
+ class="ti ti-layout-sidebar-left-collapse"></i>
10
+ <i
11
+ v-else
12
+ class="ti ti-layout-sidebar-left-expand"></i>
13
+
14
+ <span
15
+ v-if="showPoint"
16
+ class="absolute top-0 right-0 h-2 w-2 rounded-full bg-red-500 border border-white"></span>
17
+ </a>
18
+ </template>
19
+
20
+ <script lang="ts" setup>
21
+ import {ref, computed, useSlots, onMounted, watch, watchEffect, inject} from "vue";
22
+ import {useRouter, RouterLink, RouterView} from "vue-router";
23
+ import {useGlobalSettingsStore} from "@/stores/globalSettings";
24
+ import {useGlobalState} from "@/stores/globalState";
25
+ import {useSupertokens} from "@/stores/supertokens";
26
+ import * as asserts from "@/logic/asserts";
27
+ import * as events from "@/logic/events";
28
+ import * as e from "@/logic/enums";
29
+ import * as settings from "@/logic/settings";
30
+
31
+ const globalSettings = useGlobalSettingsStore();
32
+
33
+ const eventsView = inject<events.EventsViewName>("eventsViewName");
34
+
35
+ asserts.defined(eventsView);
36
+
37
+ const title = computed(() => {
38
+ return globalSettings.showSidebar ? "Hide sidebar" : "Show sidebar";
39
+ });
40
+
41
+ const showPoint = computed(() => {
42
+ return !globalSettings.showSidebar && globalSettings.showSidebarPoint;
43
+ });
44
+
45
+ function onClick() {
46
+ globalSettings.showSidebar = !globalSettings.showSidebar;
47
+
48
+ asserts.defined(eventsView);
49
+
50
+ events.sidebarStateChanged({
51
+ view: eventsView,
52
+ subEvent: globalSettings.showSidebar ? "show" : "hide",
53
+ source: "top_sidebar_button"
54
+ });
55
+ }
56
+ </script>
@@ -15,6 +15,10 @@
15
15
  }
16
16
  }
17
17
 
18
+ .ffun-side-panel-collapsed {
19
+ @apply px-4 w-16 bg-slate-50 flex-shrink-0;
20
+ }
21
+
18
22
  .ffun-body-panel {
19
23
  @apply flex-grow;
20
24
  }
@@ -1,10 +1,14 @@
1
1
  <template>
2
2
  <div class="ffun-side-panel-layout">
3
- <div class="ffun-side-panel">
4
- <div class="ffun-page-header">
5
- <div class="ffun-page-header-title">
3
+ <div
4
+ v-if="globalSettings.showSidebar"
5
+ class="ffun-side-panel">
6
+ <div class="ffun-page-header pr-0 mr-0 flex min-w-full">
7
+ <div class="ffun-page-header-title grow">
6
8
  <slot name="main-header"></slot>
7
9
  </div>
10
+
11
+ <side-panel-collapse-button />
8
12
  </div>
9
13
 
10
14
  <hr />
@@ -49,6 +53,8 @@
49
53
  <div class="ffun-body-panel">
50
54
  <div class="ffun-page-header">
51
55
  <div class="ffun-page-header-left-block">
56
+ <side-panel-collapse-button v-if="!globalSettings.showSidebar" />
57
+
52
58
  <a
53
59
  v-if="homeButton"
54
60
  :href="router.resolve({name: 'main', params: {}}).href"
@@ -92,7 +98,7 @@
92
98
  </div>
93
99
  </div>
94
100
 
95
- <hr class="my-2 border-slate-400" />
101
+ <hr class="mx-4 my-2 border-slate-400" />
96
102
 
97
103
  <main class="mb-4 px-4 min-h-screen">
98
104
  <slot></slot>
@@ -15,6 +15,9 @@ export type EventsViewName =
15
15
  | "collections";
16
16
  export type TagChangeSource = "tags_filter" | "entry_record" | "rule_record";
17
17
 
18
+ export type SidebarVisibilityChangeEvent = "hide" | "show";
19
+ export type SidebarVisibilityChangeSource = "top_sidebar_button";
20
+
18
21
  export async function newsLinkOpened({entryId, view}: {entryId: t.EntryId; view: EventsViewName}) {
19
22
  await api.trackEvent({
20
23
  name: "news_link_opened",
@@ -39,6 +42,23 @@ export async function socialLinkClicked({linkType, view}: {linkType: string; vie
39
42
  });
40
43
  }
41
44
 
45
+ export async function sidebarStateChanged({
46
+ subEvent,
47
+ view,
48
+ source
49
+ }: {
50
+ subEvent: SidebarVisibilityChangeEvent;
51
+ view: EventsViewName;
52
+ source: SidebarVisibilityChangeSource;
53
+ }) {
54
+ await api.trackEvent({
55
+ name: "sidebar_state_changed",
56
+ view: view,
57
+ sub_event: subEvent,
58
+ source: source
59
+ });
60
+ }
61
+
42
62
  export async function tagStateChanged({
43
63
  tag,
44
64
  fromState,
@@ -161,3 +161,14 @@ export function setSyncingTagsWithRoute({tagsStates, route, router}: {tagsStates
161
161
  });
162
162
  });
163
163
  }
164
+
165
+ // must be called synchoronously from the view
166
+ export function setSyncingTagsSidebarPoint({tagsStates, globalSettings}: {tagsStates: Storage; globalSettings: any}) {
167
+ watch(
168
+ tagsStates,
169
+ () => {
170
+ globalSettings.showSidebarPoint = tagsStates.hasSelectedTags;
171
+ },
172
+ {immediate: true}
173
+ );
174
+ }
package/src/main.ts CHANGED
@@ -67,6 +67,8 @@ import MainNewsTitle from "./components/main/NewsTitle.vue";
67
67
  import MainHeaderLine from "./components/main/HeaderLine.vue";
68
68
  import MainBlock from "./components/main/Block.vue";
69
69
 
70
+ import SidePanelCollapseButton from "./components/side_pannel/CollapseButton.vue";
71
+
70
72
  import WideLayout from "./layouts/WideLayout.vue";
71
73
  import SidePanelLayout from "./layouts/SidePanelLayout.vue";
72
74
 
@@ -137,6 +139,8 @@ app.component("MainNewsTitle", MainNewsTitle);
137
139
  app.component("MainHeaderLine", MainHeaderLine);
138
140
  app.component("MainBlock", MainBlock);
139
141
 
142
+ app.component("SidePanelCollapseButton", SidePanelCollapseButton);
143
+
140
144
  app.component("WideLayout", WideLayout);
141
145
  app.component("SidePanelLayout", SidePanelLayout);
142
146
 
@@ -12,6 +12,8 @@ export const useGlobalSettingsStore = defineStore("globalSettings", () => {
12
12
  // General
13
13
  const mainPanelMode = ref(e.MainPanelMode.Entries);
14
14
  const dataVersion = ref(0);
15
+ const showSidebar = ref(true);
16
+ const showSidebarPoint = ref(false);
15
17
 
16
18
  // Entries
17
19
  const lastEntriesPeriod = ref(e.LastEntriesPeriod.Day3);
@@ -70,6 +72,8 @@ export const useGlobalSettingsStore = defineStore("globalSettings", () => {
70
72
  info,
71
73
  feedsOrder,
72
74
  failedFeedsFirst,
73
- rulesOrder
75
+ rulesOrder,
76
+ showSidebar,
77
+ showSidebarPoint
74
78
  };
75
79
  });
@@ -102,6 +102,11 @@
102
102
  router
103
103
  });
104
104
 
105
+ tagsFilterState.setSyncingTagsSidebarPoint({
106
+ tagsStates: tagsStates.value as unknown as tagsFilterState.Storage,
107
+ globalSettings
108
+ });
109
+
105
110
  globalSettings.mainPanelMode = e.MainPanelMode.Entries;
106
111
 
107
112
  globalSettings.updateDataVersion();
@@ -56,13 +56,18 @@
56
56
  provide("tagsStates", tagsStates);
57
57
  provide("eventsViewName", "rules");
58
58
 
59
+ const globalSettings = useGlobalSettingsStore();
60
+
59
61
  tagsFilterState.setSyncingTagsWithRoute({
60
62
  tagsStates: tagsStates.value as unknown as tagsFilterState.Storage,
61
63
  route,
62
64
  router
63
65
  });
64
66
 
65
- const globalSettings = useGlobalSettingsStore();
67
+ tagsFilterState.setSyncingTagsSidebarPoint({
68
+ tagsStates: tagsStates.value as unknown as tagsFilterState.Storage,
69
+ globalSettings
70
+ });
66
71
 
67
72
  globalSettings.mainPanelMode = e.MainPanelMode.Rules;
68
73