From ff5f91b262fb97b8a41b400ac3d5de76c449c621 Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 12 Jul 2026 13:46:48 +0000 Subject: [PATCH 1/4] fix(activity): detect Android device at runtime for view selection VUE_APP_ON_ANDROID is set at build time and only covers the embedded Android webui. When a desktop browser views an Android device's data, the default views always show desktop views (Top Window Titles etc.) instead of the Android summary view. Fix by replacing the mapState('views') with an explicit computed that checks bucketsStore.available(host).android at runtime. If the host has Android buckets but no window buckets, return androidViews regardless of build env. --- src/stores/views.ts | 2 +- src/views/activity/Activity.vue | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/stores/views.ts b/src/stores/views.ts index 8568dbef..4191b4db 100644 --- a/src/stores/views.ts +++ b/src/stores/views.ts @@ -54,7 +54,7 @@ const desktopViews: View[] = [ }, ]; -const androidViews = [ +export const androidViews: View[] = [ { id: 'summary', name: 'Summary', diff --git a/src/views/activity/Activity.vue b/src/views/activity/Activity.vue index c3b60a63..51946572 100644 --- a/src/views/activity/Activity.vue +++ b/src/views/activity/Activity.vue @@ -229,7 +229,8 @@ import 'vue-awesome/icons/ellipsis-v'; import { useSettingsStore } from '~/stores/settings'; import { useCategoryStore } from '~/stores/categories'; import { useActivityStore, QueryOptions } from '~/stores/activity'; -import { useViewsStore } from '~/stores/views'; +import { useViewsStore, androidViews } from '~/stores/views'; +import { useBucketsStore } from '~/stores/buckets'; export default { name: 'Activity', @@ -254,6 +255,7 @@ export default { data: function () { return { activityStore: useActivityStore(), + bucketsStore: useBucketsStore(), categoryStore: useCategoryStore(), viewsStore: useViewsStore(), settingsStore: useSettingsStore(), @@ -275,7 +277,17 @@ export default { }; }, computed: { - ...mapState(useViewsStore, ['views']), + views(): import('~/stores/views').View[] { + // Use Android views when the current host is an Android device. + // VUE_APP_ON_ANDROID is a build-time flag that only applies when the webui + // is embedded in the Android app itself. When browsing Android device data + // from a desktop browser we need a runtime check instead. + const available = this.bucketsStore.available(this.host); + if (available.android && !available.window) { + return androidViews; + } + return this.viewsStore.views; + }, ...mapState(useSettingsStore, ['devmode']), ...mapState(useSettingsStore, ['always_active_pattern']), From 317a7f5b00f6311c0fd464cdaf3cdbd1efda0f1f Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 12 Jul 2026 13:55:13 +0000 Subject: [PATCH 2/4] fix(activity): apply Android view detection in ActivityView child component The parent Activity.vue now returns androidViews for the tab list when the host is an Android device, but ActivityView.vue was still resolving the current view from viewsStore.views (desktop views). This caused the child to render desktop-view elements (e.g. Top Window Titles) even when the Android Summary tab was selected. Fix: replicate the same runtime bucket check (available.android && !available.window) in ActivityView.vue, reading the host from $route.params.host. Android hosts now get androidViews elements; desktop hosts and the build-time VUE_APP_ON_ANDROID path are unchanged. --- src/views/activity/ActivityView.vue | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/views/activity/ActivityView.vue b/src/views/activity/ActivityView.vue index c5c3fa52..318c05ee 100644 --- a/src/views/activity/ActivityView.vue +++ b/src/views/activity/ActivityView.vue @@ -59,10 +59,10 @@ import 'vue-awesome/icons/times'; import 'vue-awesome/icons/trash'; import 'vue-awesome/icons/undo'; -import { mapState } from 'pinia'; import draggable from 'vuedraggable'; -import { useViewsStore } from '~/stores/views'; +import { useViewsStore, androidViews } from '~/stores/views'; +import { useBucketsStore } from '~/stores/buckets'; export default { name: 'ActivityView', @@ -73,10 +73,23 @@ export default { view_id: { type: String, default: 'default' }, }, data() { - return { editing: false }; + return { editing: false, bucketsStore: useBucketsStore() }; }, computed: { - ...mapState(useViewsStore, ['views']), + views: function () { + // Use Android views when the current host is an Android device. + // Mirrors the same runtime check in Activity.vue so the child view + // resolves its elements from the correct view list instead of always + // falling back to the stored desktop views. + const host = this.$route.params.host; + if (host) { + const available = this.bucketsStore.available(host); + if (available.android && !available.window) { + return androidViews; + } + } + return useViewsStore().views; + }, view: function () { if (this.view_id == 'default') { return this.views[0]; From 48f1fed3bd0ebae56c4cb8193a1eaab17c0c867f Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 12 Jul 2026 14:11:45 +0000 Subject: [PATCH 3/4] refactor(activity): move Android host detection into viewsForHost store action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove duplicated bucket-check computed properties from Activity.vue and ActivityView.vue. Instead add a viewsForHost(host) action on useViewsStore that centralises the runtime android-vs-desktop detection. Components now call viewsStore.viewsForHost(host) — a single call into the store — rather than importing androidViews and useBucketsStore directly. --- src/stores/views.ts | 10 +++++++++- src/views/activity/Activity.vue | 14 ++------------ src/views/activity/ActivityView.vue | 18 +++--------------- 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/stores/views.ts b/src/stores/views.ts index 4191b4db..3139042f 100644 --- a/src/stores/views.ts +++ b/src/stores/views.ts @@ -1,5 +1,6 @@ import { defineStore } from 'pinia'; import { useSettingsStore } from './settings'; +import { useBucketsStore } from './buckets'; interface IElement { type: string; @@ -68,7 +69,6 @@ export const androidViews: View[] = [ }, ]; -// FIXME: Decide depending on what kind of device is being viewed, not from which device it is being viewed from. export const defaultViews = !process.env.VUE_APP_ON_ANDROID ? desktopViews : androidViews; interface State { @@ -107,6 +107,14 @@ export const useViewsStore = defineStore('views', { restoreDefaults(this: State) { this.views = defaultViews; }, + viewsForHost(host: string): View[] { + const bucketsStore = useBucketsStore(); + const available = bucketsStore.available(host); + if (available.android && !available.window) { + return androidViews; + } + return this.views; + }, addView(this: State, view: View) { this.views.push({ ...view, elements: [] }); }, diff --git a/src/views/activity/Activity.vue b/src/views/activity/Activity.vue index 51946572..557b8a23 100644 --- a/src/views/activity/Activity.vue +++ b/src/views/activity/Activity.vue @@ -229,8 +229,7 @@ import 'vue-awesome/icons/ellipsis-v'; import { useSettingsStore } from '~/stores/settings'; import { useCategoryStore } from '~/stores/categories'; import { useActivityStore, QueryOptions } from '~/stores/activity'; -import { useViewsStore, androidViews } from '~/stores/views'; -import { useBucketsStore } from '~/stores/buckets'; +import { useViewsStore } from '~/stores/views'; export default { name: 'Activity', @@ -255,7 +254,6 @@ export default { data: function () { return { activityStore: useActivityStore(), - bucketsStore: useBucketsStore(), categoryStore: useCategoryStore(), viewsStore: useViewsStore(), settingsStore: useSettingsStore(), @@ -278,15 +276,7 @@ export default { }, computed: { views(): import('~/stores/views').View[] { - // Use Android views when the current host is an Android device. - // VUE_APP_ON_ANDROID is a build-time flag that only applies when the webui - // is embedded in the Android app itself. When browsing Android device data - // from a desktop browser we need a runtime check instead. - const available = this.bucketsStore.available(this.host); - if (available.android && !available.window) { - return androidViews; - } - return this.viewsStore.views; + return this.viewsStore.viewsForHost(this.host); }, ...mapState(useSettingsStore, ['devmode']), ...mapState(useSettingsStore, ['always_active_pattern']), diff --git a/src/views/activity/ActivityView.vue b/src/views/activity/ActivityView.vue index 318c05ee..33cb49ba 100644 --- a/src/views/activity/ActivityView.vue +++ b/src/views/activity/ActivityView.vue @@ -61,8 +61,7 @@ import 'vue-awesome/icons/undo'; import draggable from 'vuedraggable'; -import { useViewsStore, androidViews } from '~/stores/views'; -import { useBucketsStore } from '~/stores/buckets'; +import { useViewsStore } from '~/stores/views'; export default { name: 'ActivityView', @@ -73,22 +72,11 @@ export default { view_id: { type: String, default: 'default' }, }, data() { - return { editing: false, bucketsStore: useBucketsStore() }; + return { editing: false }; }, computed: { views: function () { - // Use Android views when the current host is an Android device. - // Mirrors the same runtime check in Activity.vue so the child view - // resolves its elements from the correct view list instead of always - // falling back to the stored desktop views. - const host = this.$route.params.host; - if (host) { - const available = this.bucketsStore.available(host); - if (available.android && !available.window) { - return androidViews; - } - } - return useViewsStore().views; + return useViewsStore().viewsForHost(this.$route.params.host || ''); }, view: function () { if (this.view_id == 'default') { From 7d645a370197e73b65f5532d0d33c978af5d5b0b Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 12 Jul 2026 14:24:32 +0000 Subject: [PATCH 4/4] fix(buckets): remove redundant Hostname column from per-device bucket table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Hostname is already displayed prominently in each device card's header. Showing it again as a column inside the per-device table is redundant and squeezes the table on phone screens. Remove it and redistribute the column widths (id: 45%→65%, last_updated: 15%→20%, actions: 15% unchanged). --- src/views/Buckets.vue | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/views/Buckets.vue b/src/views/Buckets.vue index 45609575..da8202d2 100644 --- a/src/views/Buckets.vue +++ b/src/views/Buckets.vue @@ -262,18 +262,13 @@ export default { key: 'id', label: this.$t('buckets.bucketId'), sortable: true, - thStyle: { width: '45%' }, - }, - { - key: 'hostname', - sortable: true, - thStyle: { width: '25%' }, + thStyle: { width: '65%' }, }, { key: 'last_updated', label: this.$t('buckets.updated'), sortable: true, - thStyle: { width: '15%' }, + thStyle: { width: '20%' }, }, { key: 'actions',