Skip to content

Commit 196da55

Browse files
authored
✨ Persist profile settings for default checkin visibility (#2437)
1 parent 914f8a3 commit 196da55

File tree

7 files changed

+190
-2
lines changed

7 files changed

+190
-2
lines changed

package-lock.json

+65
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
"luxon": "^3.4.4",
3030
"mdb-ui-kit": "^6.4.1",
3131
"notyf": "^3.10.0",
32+
"pinia": "^2.1.7",
33+
"pinia-plugin-persistedstate": "^3.2.1",
3234
"vue": "^3.3.4"
3335
}
3436
}

resources/js/app.js

+7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import CheckinSuccessHelper from "../vue/components/CheckinSuccessHelper.vue";
1616
import {i18nVue} from "laravel-vue-i18n";
1717
import TagHelper from "../vue/components/TagHelper.vue";
1818
import TripCreationForm from "../vue/components/TripCreation/TripCreationForm.vue";
19+
import {createPinia} from 'pinia'
20+
import piniaPluginPersistedsState from 'pinia-plugin-persistedstate'
1921

2022
window.notyf = new Notyf({
2123
duration: 5000,
@@ -49,6 +51,8 @@ document.addEventListener("DOMContentLoaded", function () {
4951
let fallbackLang = "en";
5052
const urlParams = new URLSearchParams(window.location.search);
5153
const lang = urlParams.get("language");
54+
const pinia = createPinia();
55+
pinia.use(piniaPluginPersistedsState);
5256

5357
if (lang && lang.startsWith("de_")) {
5458
fallbackLang = "de";
@@ -58,6 +62,7 @@ document.addEventListener("DOMContentLoaded", function () {
5862
const app = createApp({});
5963
app.component("NotificationBell", NotificationBell);
6064
app.config.devtools = true;
65+
app.use(pinia);
6166
app.use(i18nVue, {
6267
fallbackLang: fallbackLang,
6368
resolve: (lang) => import(`../../lang/${lang}.json`)
@@ -68,6 +73,7 @@ document.addEventListener("DOMContentLoaded", function () {
6873
if (document.getElementById("activeJourneys")) {
6974
const app2 = createApp({});
7075
app2.component("ActiveJourneyMap", ActiveJourneyMap);
76+
app2.use(pinia);
7177
app2.use(i18nVue, {
7278
fallbackLang: fallbackLang,
7379
resolve: (lang) => import(`../../lang/${lang}.json`)
@@ -79,6 +85,7 @@ document.addEventListener("DOMContentLoaded", function () {
7985
const app3 = createApp({});
8086
app3.component("Stationboard", Stationboard);
8187
app3.component("Stationautocomplete", StationAutocomplete);
88+
app3.use(pinia);
8289
app3.use(i18nVue, {
8390
fallbackLang: fallbackLang,
8491
resolve: (lang) => import(`../../lang/${lang}.json`)

resources/types/ProfileSettings.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export type ProfileSettings = {
2+
username: string;
3+
displayName: string;
4+
profilePicture: string | null;
5+
privateProfile: boolean;
6+
preventIndex: boolean;
7+
defaultStatusVisibility: number;
8+
privacyHideDays: number;
9+
password: boolean;
10+
email: string | null;
11+
emailVerified: boolean;
12+
profilePictureSet: boolean;
13+
twitter: string | null;
14+
mastodon: string | null;
15+
mastodonVisibility: number;
16+
};

resources/vue/components/CheckinInterface.vue

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@
22
import {DateTime} from "luxon";
33
import {Notyf} from "notyf";
44
import {trans} from "laravel-vue-i18n";
5+
import {useProfileSettingsStore} from "../stores/profileSettings";
56
67
export default {
8+
setup() {
9+
const profileStore = useProfileSettingsStore();
10+
profileStore.fetchSettings();
11+
12+
return { profileStore };
13+
},
714
name: "CheckinInterface",
815
props: {
916
selectedDestination: {
@@ -20,7 +27,7 @@ export default {
2027
allowedChars: 280,
2128
statusText: "",
2229
toot: false,
23-
visibility: 0,
30+
visibility: this.profileStore.getDefaultStatusVisibility,
2431
business: 0,
2532
loading: false,
2633
notyf: new Notyf({position: {x: "right", y: "bottom"}}),
@@ -126,7 +133,7 @@ export default {
126133
</small>
127134

128135
<div class="mt-2">
129-
<div class="col-auto btn-group me-1">
136+
<div class="col-auto btn-group me-1" :class="{'d-none' : profileStore.getMastodon == null}" >
130137
<input type="checkbox" class="btn-check" autocomplete="off" v-model="toot" autocompleted="" id="toot_check" :disabled="visibility === 3">
131138
<label class="btn btn-sm btn-outline-mastodon" for="toot_check" style="">
132139
<i class="fab fa-mastodon"></i>
+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import {defineStore} from "pinia";
2+
import { ProfileSettings } from "../../types/ProfileSettings";
3+
4+
export const useProfileSettingsStore = defineStore('profileSettings', {
5+
// because of the persist option. This option is defined in the pinia persisted state plugin
6+
// @types-ignore
7+
persist: true,
8+
state: () => ({
9+
settings: null as ProfileSettings | null,
10+
loading: false,
11+
error: null as unknown | null,
12+
refreshed: "2021-08-01T12:00:00Z"
13+
}),
14+
getters: {
15+
getDisplayName(): string {
16+
return this.settings ? this.settings.displayName : '';
17+
},
18+
getUsername(): string {
19+
return this.settings ? this.settings.username : '';
20+
},
21+
getProfilePicture(): string | null {
22+
return this.settings ? this.settings.profilePicture : '';
23+
},
24+
isPrivateProfile(): boolean {
25+
return this.settings ? this.settings.privateProfile : false;
26+
},
27+
isPreventIndex(): boolean {
28+
return this.settings ? this.settings.preventIndex : false;
29+
},
30+
getDefaultStatusVisibility(): number {
31+
return this.settings ? this.settings.defaultStatusVisibility : 0;
32+
},
33+
getPrivacyHideDays(): number {
34+
return this.settings ? this.settings.privacyHideDays : 0;
35+
},
36+
getEmail(): string | null {
37+
return this.settings ? this.settings.email : null;
38+
},
39+
isEmailVerified(): boolean {
40+
return this.settings ? this.settings.emailVerified : false;
41+
},
42+
isProfilePictureSet(): boolean {
43+
return this.settings ? this.settings.profilePictureSet : false;
44+
},
45+
getTwitter(): string | null {
46+
return this.settings ? this.settings.twitter : null;
47+
},
48+
getMastodon(): string | null {
49+
return this.settings ? this.settings.mastodon : null;
50+
},
51+
getMastodonVisibility(): number {
52+
return this.settings ? this.settings.mastodonVisibility : 0;
53+
}
54+
},
55+
actions: {
56+
async fetchSettings() : Promise<void>{
57+
// Fetch Data every 15 Minutes
58+
// ToDo: reduce interval
59+
// ToDo: refresh with settings update
60+
// ToDo: invalidate when logging out
61+
if (this.refreshed && (new Date().getTime() - new Date(this.refreshed).getTime()) < 60 * 15 * 1000) {
62+
return;
63+
}
64+
this.loading = true;
65+
try {
66+
this.settings = await fetch('/api/v1/settings/profile')
67+
.then((response: { json: () => any; }) => response.json())
68+
.then((data: { data: any; }) => data.data);
69+
this.refreshed = new Date().toString();
70+
} catch (error) {
71+
this.error = error;
72+
} finally {
73+
this.loading = false;
74+
}
75+
}
76+
}
77+
});

tsconfig.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es2016",
4+
"module": "commonjs",
5+
"esModuleInterop": true,
6+
"forceConsistentCasingInFileNames": true,
7+
"strict": true,
8+
"skipLibCheck": true,
9+
"lib": [
10+
"ES2015",
11+
"dom"
12+
]
13+
}
14+
}

0 commit comments

Comments
 (0)