Settings
Library provide an easy way to integrate settings to your web extension through an Options page.
TIP
Since it uses Sync storage, you should update your extension permissions, edit your manifest.json
with:
{
"permissions": ["storage"]
}
Definition
Your settings must match InterfaceSettings
interface:
export interface InterfaceSettings {
[k: string]: InterfaceSettingsItem;
}
export interface InterfaceSettingsItem {
type: 'boolean'; // for now, it only supports boolean
label: string;
help?: string;
defaultValue?: any;
value?: any;
children?: InterfaceSettings;
}
Here is an example of settings from a web extension which uses sounds, notifications, and Twitch helper:
WARNING
We highly recommend to define your settings in a single file, src/settings.ts
for example.
// src/settings.ts
import { InterfaceSettings } from '@kocal/web-extension-library';
export default {
// -- Simple setting
// Should we play sounds?
playSounds: {
type: 'boolean',
label: 'Play sounds',
defaultValue: false,
},
// -- If your setting is more complex, you can use `children` object
// Should we display any notifications ?
showNotifications: {
type: 'boolean',
label: 'Notifications',
defaultValue: true,
children: {
// Show notifications at browser boot?
atBoot: {
type: 'boolean',
label: 'At browser boot',
defaultValue: true,
},
// Show notifications when a stream updates its title?
onTitleUpdate: {
type: 'boolean',
label: 'At each show',
help: 'Display a notification when a stream updates its title',
defaultValue: false,
},
},
},
} as InterfaceSettings;
Depending of how you handle your options page, this is what Solary french extension displays:
Note: Solary only use settings for notifications.
Registration
Before using your settings, you must register them with regiterSettings
.
A call to loadSettings()
is automatically made to retrieve settings from Sync storage.
In your options page:
import { registerSettings } from '@kocal/web-extension-library';
import settings from './path/to/your/settings.ts';
registerSettings(settings)
.then(() => {
// Display your settings interface
})
.catch(error => {
console.error(error);
});
For example, this is how Solary implements its settings interface with Vue.js:
<template>
<div>
<template v-if="loading">
Loading parameters...
</template>
<template v-else-if="error">
{{ error.message }}
</template>
<template v-else>
<!-- Component which renders settings tree -->
<settings :settings="settings"/>
</template>
</div>
</template>
<script>
import { registerSettings, getSettings, setSettingValue } from '@kocal/web-extension-library';
import settings from '../store/settings';
export default {
components: { Settings },
data: () => ({
settings: {},
loading: true,
error: null,
}),
created() {
registerSettings(settings) // will hydrate `settings` object
.then(() => {
this.loading = false;
this.$set(this, 'settings', getSettings());
// update some settings, it will synchronize them with sync storage...
setSettingValue('showNotifications', true)
.then(() => console.log('success'));
setSettingValue('showNotifications.onTitleUpdate', true)
.then(() => console.log('success'));
})
.catch(error => {
this.error = error;
this.loading = false;
});
},
};
</script>
Usage
If you want to use your settings in an other page than options
(e.g.: background
),
you should import and register your settings again, because it's possible that your options page has
never been opened and your settings are not synchronized yet.
WARNING
The method registerSettings
should be called only one time per page (options
and background
).
WARNING
If your background runs an interval (e.g.: fetch some twitch streams each 2 minutes),
then you must load your settings with loadSettings()
in order to keep them synchronized.
// src/background.ts
import { registerSettings, loadSettings, getSettingValue, setSettingValue } from '@kocal/web-extension-library';
import settings from './path/to/your/settings.ts';
registerSettings(settings)
.then(() => {
bootBackgroundApp();
});
function bootBackgroundApp() {
// do stuff...
setInterval(() => {
// You MUST call this function at least one time before using settings,
// in order to keep them synchronized with options page
loadSettings()
.then(() => {
if (getSettingValue('showNotifications') === true) {
// Show a notification...
}
if (getSettingValue('showNotifications.onTitleUpdate') === true) {
// Show a notification...
}
})
}, 1000 * 60 * 2);
}