Skip to content

Commit 4d7796d

Browse files
committed
feat: implement a better at a glance widget
1 parent dfa85ff commit 4d7796d

File tree

6 files changed

+129
-9
lines changed

6 files changed

+129
-9
lines changed

src/components/home/glance/AtAGlance.vue

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,44 @@
11
<script setup lang="ts">
2+
import { computed, inject } from "vue";
3+
4+
import { ApplicationNamespace, GlobalStatesContextKey } from "@/constants/application.ts";
5+
import General from "@/lib/general";
6+
import { log } from "@/lib/logging/scopes/log.ts";
7+
import type { ContextGlobalStatesType } from "@/types/application/global-states.type.ts";
8+
import type { AtAGlanceType } from "@/types/ui/at-a-glance.type.ts";
9+
10+
const globalStates = inject<ContextGlobalStatesType>(GlobalStatesContextKey);
11+
12+
const currentGlance = computed((): AtAGlanceType => {
13+
const configGlance: {
14+
"title" : string | null | undefined;
15+
"subtitle": string | null | undefined;
16+
} = {
17+
"title" : globalStates?.layout?.atAGlance?.title,
18+
"subtitle": globalStates?.layout?.atAGlance?.subtitle,
19+
};
20+
21+
if (!configGlance.title || !configGlance.subtitle) {
22+
log.debug("No custom 'At a Glance' text in the config, using defaults");
23+
const currentTitle = window[ApplicationNamespace].__internals.atAGlance?.title;
24+
const newAtAGlance = General.getAtAGlance(currentTitle);
25+
26+
window[ApplicationNamespace].__internals.atAGlance = newAtAGlance;
27+
28+
return newAtAGlance;
29+
}
30+
31+
log.debug("Showing a custom 'At a Glance' text:", JSON.stringify(
32+
configGlance,
33+
null,
34+
2,
35+
));
36+
37+
return {
38+
"title" : configGlance.title,
39+
"subtitle": configGlance.subtitle,
40+
};
41+
});
242
</script>
343

444
<template>
@@ -10,13 +50,13 @@
1050
id="__home-page__header-title"
1151
class="w-fit cursor-pointer border border-transparent rounded-md p-2 text-3xl leading-none transition-[background-color,border-color] hover:border-[theme(colors.white/.3)] hover:bg-[theme(colors.white/.1)]"
1252
>
13-
A promising future
53+
{{ currentGlance.title }}
1454
</div>
1555
<div
1656
id="__home-page__header-subtitle"
1757
class="w-fit cursor-pointer border border-transparent rounded-md p-2 text-lg text-neutral-300 leading-none transition-[background-color,border-color] hover:border-[theme(colors.white/.3)] hover:bg-[theme(colors.white/.1)]"
1858
>
19-
Without JavaScript
59+
{{ currentGlance.subtitle }}
2060
</div>
2161
</div>
2262
</template>

src/declarations.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import type {
2525
import type { RouteType } from "@/types/application/route.type.ts";
2626
import type { HookReturnType } from "@/types/extensions/hook-return.type.ts";
2727
import type { TranslationsType } from "@/types/translations/translations.type.ts";
28+
import type { AtAGlanceType } from "@/types/ui/at-a-glance.type.ts";
2829

2930
/* Expand the globals with Kaede and Tauri namespaces */
3031
declare global {
@@ -59,7 +60,7 @@ declare global {
5960
/**
6061
* Workarounds for application internals.
6162
*
62-
* Should not be modified by extensions
63+
* These fields are not intended to be modified by extensions
6364
*/
6465
"__internals": {
6566
// Gets current application's global states (use 'libs.GlobalStateHelpers#get')
@@ -72,6 +73,8 @@ declare global {
7273
"initialPortable" ?: boolean;
7374
// Application's base directory state before launcher initialization
7475
"initialBaseDirectory"?: string;
76+
// A temporary storage for the 'At a Glance' widget
77+
"atAGlance" ?: AtAGlanceType;
7578
};
7679

7780
/**

src/lib/general/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { capitalize } from "@/lib/general/scopes/capitalize.ts";
22
import { checkIsPortable } from "@/lib/general/scopes/check-is-portable.ts";
3+
import { getAtAGlance } from "@/lib/general/scopes/get-at-a-glance.ts";
34
import { getBaseDirectory } from "@/lib/general/scopes/get-base-directory.ts";
45
import { getExecutableDirectory } from "@/lib/general/scopes/get-executable-directory.ts";
56
import { getRelativeDate } from "@/lib/general/scopes/get-relative-date.ts";
@@ -9,6 +10,7 @@ import { initializeLauncher } from "@/lib/general/scopes/initialize-launcher.ts"
910
export default {
1011
capitalize,
1112
checkIsPortable,
13+
getAtAGlance,
1214
getBaseDirectory,
1315
getExecutableDirectory,
1416
getRelativeDate,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type { AtAGlanceType } from "@/types/ui/at-a-glance.type.ts";
2+
3+
const atAGlanceMessages = [
4+
{
5+
"title" : "A promising future",
6+
"subtitle": "without JavaScript",
7+
},
8+
{
9+
"title" : "These messages",
10+
"subtitle": "were inspired by the \"At a Glance\" android widget",
11+
},
12+
{
13+
"title" : "Kaede",
14+
"subtitle": "was not built in a day",
15+
},
16+
{
17+
"title" : "%date%",
18+
"subtitle": "",
19+
},
20+
];
21+
22+
function transformAtAGlanceMessages(message: AtAGlanceType): AtAGlanceType {
23+
const currentDate = (new Date)
24+
.toDateString()
25+
.split(" ");
26+
27+
message.title = message.title.replace("%date%", (
28+
currentDate[0] + ", " + currentDate[1] + " " + currentDate[2]
29+
));
30+
31+
return message;
32+
}
33+
34+
export function getAtAGlance(currentTitle?: string): AtAGlanceType {
35+
const randomIndex = Math.floor(
36+
Math.random() * atAGlanceMessages.length,
37+
);
38+
const newMessage = atAGlanceMessages[randomIndex];
39+
40+
if (currentTitle === newMessage.title) {
41+
const uniqueIndex = randomIndex - 1;
42+
43+
if (uniqueIndex < 0) {
44+
return transformAtAGlanceMessages(atAGlanceMessages[randomIndex + 1]);
45+
}
46+
47+
return transformAtAGlanceMessages(atAGlanceMessages[uniqueIndex]);
48+
}
49+
50+
return transformAtAGlanceMessages(newMessage);
51+
}

src/types/ui/at-a-glance.type.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export type AtAGlanceType = {
2+
"title" : string;
3+
"subtitle": string;
4+
};

vitest.setup.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ vi.stubGlobal("window", {
88
"__internals": {
99
"getGlobalStates" : (): void => {},
1010
"changeGlobalStates": (): void => {},
11+
"initialConfig" : {},
1112
},
1213
"variables": {
1314
"rippleColor" : "",
@@ -20,11 +21,6 @@ vi.stubGlobal("window", {
2021
},
2122
"getDefaultConfig": {
2223
"before": [],
23-
"after" : [],
24-
},
25-
"onLocaleChange": {
26-
"before": [],
27-
"after" : [],
2824
},
2925
"onPagesChange": {
3026
"before": [],
@@ -46,6 +42,30 @@ vi.stubGlobal("window", {
4642
"before": [],
4743
"after" : [],
4844
},
45+
"onTranslationsChange": {
46+
"before": [],
47+
"after" : [],
48+
},
49+
"onFileSystemChange": {
50+
"before": [],
51+
"after" : [],
52+
},
53+
"onDevelopmentChange": {
54+
"before": [],
55+
"after" : [],
56+
},
57+
"onMiscChange": {
58+
"before": [],
59+
"after" : [],
60+
},
61+
"onMinecraftChange": {
62+
"before": [],
63+
"after" : [],
64+
},
65+
"onInstancesChange": {
66+
"before": [],
67+
"after" : [],
68+
},
4969
},
5070
},
5171
} satisfies {
@@ -74,4 +94,4 @@ vi.mock("@tauri-apps/api/window", async () => {
7494
} as typeof window.__TAURI__.window;
7595

7696
return mockedWindow;
77-
});
97+
});

0 commit comments

Comments
 (0)