Skip to content

Commit

Permalink
Add browser storage for settings for cases where localStorage is not …
Browse files Browse the repository at this point in the history
…available
  • Loading branch information
m-mohr committed Jun 5, 2024
1 parent c09cbd7 commit 19eb6b9
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 12 deletions.
12 changes: 10 additions & 2 deletions docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,16 @@ Otherwise, defaults to the language set for `locale`.

## storeLocale

If set to `true`, stores the locale selected by the user in the `localStorage` of the browser.
Otherwise, doesn't store the locale across browser sessions.
If set to `true` (default), stores the locale selected by the user in the storage of the browser.
If set to `false`, doesn't store the locale across browser sessions.

Depending on the browser settings, this may store in either:
- `localeStorage`
- `sessionStorage`
- cookies

In some countries this may have implications with regards to GDPR etc.
If you want to avoid this, disable this setting.

## locale

Expand Down
8 changes: 3 additions & 5 deletions src/StacBrowser.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import URI from 'urijs';
import I18N from '@radiantearth/stac-fields/I18N';
import { translateFields, API_LANGUAGE_CONFORMANCE, loadMessages } from './i18n';
import { getBest, prepareSupported } from './locale-id';
import BrowserStorage from "./browser-store";
Vue.use(AlertPlugin);
Vue.use(ButtonGroupPlugin);
Expand Down Expand Up @@ -285,11 +286,8 @@ export default {
detectLocale() {
let locale;
if (this.storeLocaleFromVueX) {
try {
locale = window.localStorage.getItem('locale');
} catch(error) {
console.error(error);
}
const storage = new BrowserStorage();
locale = storage.get('locale');
}
if (!locale && this.detectLocaleFromBrowserFromVueX && Array.isArray(navigator.languages)) {
// Detect the most suitable locale
Expand Down
156 changes: 156 additions & 0 deletions src/browser-store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import Utils from "./utils";

export default class BrowserStorage {

static JSON_INDICATOR = "\n\r";

static enabled(engine) {
if (!Utils.isObject(engine)) {
return false;
}
try {
engine.setItem('test', 'yes');
if (engine.getItem('test') === 'yes') {
engine.removeItem('test');
return true;
}
} catch(error) {
console.error(error);
}
return false;
}

constructor(session = false) {
if (session) {
if (BrowserStorage.enabled(window.sessionStorage)) {
this.engine = window.sessionStorage;
}
else if (navigator.cookieEnabled) {
this.engine = new Cookies(true);
}
else {
this.engine = new NoOp();
}
}
else {
if (BrowserStorage.enabled(window.localStorage)) {
this.engine = window.localStorage;
}
else if (navigator.cookieEnabled) {
this.engine = new Cookies();
}
else {
this.engine = new NoOp();
}
}
}

get(name) {
try {
let data = this.engine.getItem(name);
if (typeof data === 'string' && data.startsWith(BrowserStorage.JSON_INDICATOR)) {
data = JSON.parse(data.slice(BrowserStorage.JSON_INDICATOR.length));
}
return data;
} catch(error) {
console.error(error);
return null;
}
}

set(name, value) {
try {
if (typeof value !== 'string') {
value = BrowserStorage.JSON_INDICATOR + JSON.stringify(value);
}
this.engine.setItem(name, value);
} catch(error) {
console.error(error);
}
}

remove(name) {
try {
this.engine.removeItem(name);
} catch(error) {
console.error(error);
}
}

clear() {
this.engine.clear();
}

}

class Cookies {

constructor(session = false) {
this.session = session;
}

getExpiry(minutes = null) {
if (minutes === null) {
if (this.session) {
minutes = 60; // 60 minutes
}
else {
minutes = 1000 * 24 * 60; // 1000 days
}
}
const date = new Date();
date.setTime(date.getTime() + minutes * 60 * 1000);
this.epires = date.toGMTString();
}

setItem(name, value, minutes = null) {
const expires = this.getExpiry(minutes);
value = encodeURIComponent(value);
document.cookie = `${name}=${value}; expires=${expires}; path=/`;
}

getItem(name) {
const prefix = name + "=";
const parts = document.cookie.split(';');
for (let c of parts) {
c = c.trim();
if (c.startsWith(prefix)) {
const data = c.substring(prefix.length, c.length);
return decodeURIComponent(data);
}
}
return null;
}

removeItem(name) {
this.set(name, "", -1);
}

clear() {
document.cookie = '';
}

}


class NoOp {

constructor(session = false) {
this.session = session;
}

setItem(name/*, value*/) {
console.warn(`Browser storage disabled, can't store ${name}`);
}

getItem(/*name*/) {
return null;
}

removeItem(/*name*/) {
}

clear() {
}

}
8 changes: 3 additions & 5 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import STAC from '../models/stac';
import { addQueryIfNotExists, isAuthenticationError, Loading, processSTAC, proxyUrl, unproxyUrl, stacRequest } from './utils';
import { getBest } from '../locale-id';
import { TYPES } from "../components/ApiCapabilitiesMixin";
import BrowserStorage from "../browser-store.js";

function getStore(config, router) {
// Local settings (e.g. for currently loaded STAC entity)
Expand Down Expand Up @@ -634,11 +635,8 @@ function getStore(config, router) {
await cx.dispatch('config', {locale});

if (cx.state.storeLocale && userSelected) {
try {
window.localStorage.setItem('locale', locale);
} catch (error) {
console.error(error);
}
const storage = new BrowserStorage();
locale = storage.set('locale', locale);
}

// Locale for UI
Expand Down

0 comments on commit 19eb6b9

Please sign in to comment.