Skip to content

Commit

Permalink
feat: Add ability to save and restore settings and tasks (#228)
Browse files Browse the repository at this point in the history
* feat: Add basic export and import buttons

* feat: Improve settings management button designs and add i18n

* feat: Make leading the same on settings manage description
  • Loading branch information
Hanziness committed May 23, 2022
1 parent e85ce8e commit df3097b
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 5 deletions.
30 changes: 30 additions & 0 deletions components/settings/exportButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<button class="px-4 py-3 transition border-2 border-red-400 rounded-full select-none dark:shadow-none hover:bg-red-400 active:bg-red-500 active:border-red-500 active:shadow-red-200 active:shadow-md" @click="downloadSettings" v-text="$i18n.t('settings.manage.buttons.save')" />
</template>

<script>
import { useSettings } from '@/stores/settings'
import { useTasklist } from '@/stores/tasklist'
export default {
methods: {
downloadSettings () {
const settings = useSettings().$state
const tasklist = useTasklist().$state
const downloadObject = {
settings,
tasklist
}
const downloadElement = document.createElement('a')
downloadElement.href = `data:text/plain;charset=utf-8,${encodeURIComponent(JSON.stringify(downloadObject))}`
downloadElement.download = 'anotherpomodoro-settings.json'
downloadElement.style.display = 'none'
document.body.appendChild(downloadElement)
downloadElement.click()
document.body.removeChild(downloadElement)
}
}
}
</script>
53 changes: 53 additions & 0 deletions components/settings/importButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<button class="px-6 py-3 transition border-2 border-red-400 rounded-full select-none dark:shadow-none hover:bg-red-400 active:bg-red-500 active:border-red-500 active:shadow-red-200 active:shadow-md" @click="openFileDialog">
<input ref="fileinput" accept=".json" type="file" hidden @change="importFile">
<span v-text="$i18n.t('settings.manage.buttons.load')" />
</button>
</template>

<script>
import { useSettings } from '~/stores/settings'
import { useTasklist } from '~/stores/tasklist'
function filterImportedObject (store, objectToImport) {
const storeKeys = Object.keys(store.$state)
return Object
.keys(objectToImport)
.filter(key => storeKeys.includes(key))
.reduce((prev, key) => Object.assign(prev, { [key]: objectToImport[key] }), {})
}
export default {
methods: {
openFileDialog () {
this.$refs.fileinput.click()
},
importFile () {
// try to get file from the input field
const file = this.$refs.fileinput.files[0]
if (!file) {
return
}
// read file
const reader = new FileReader()
reader.onload = (e) => {
const fileContents = e.target.result
// try to patch settings and task list with the imported values
try {
const importedValues = JSON.parse(fileContents)
const settingsStore = useSettings()
const tasklistStore = useTasklist()
settingsStore.$patch(filterImportedObject(settingsStore, importedValues.settings))
tasklistStore.$patch(filterImportedObject(tasklistStore, importedValues.tasklist))
} catch (err) {
console.warn(err)
}
}
reader.readAsText(file)
}
}
}
</script>
23 changes: 18 additions & 5 deletions components/settings/settingsPanel.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<section v-show="processedValue" class="md:p-4 md:max-w-screen-sm fixed z-40 w-full h-full p-0">
<div class="md:rounded-lg dark:bg-gray-900 dark:text-gray-50 flex flex-col h-full overflow-hidden bg-white rounded-none shadow-lg">
<section v-show="processedValue" class="fixed z-40 w-full h-full p-0 md:p-4 md:max-w-screen-sm">
<div class="flex flex-col h-full overflow-hidden bg-white rounded-none shadow-lg md:rounded-lg dark:bg-gray-900 dark:text-gray-50">
<h1 class="px-4 mt-4 mb-2 text-xl font-bold uppercase">
<span>{{ $i18n.t('settings.heading') }}</span>
<UiButton :aria-label="$i18n.t('settings.buttons.close')" subtle class="float-right -mt-2 -mr-2" tabindex="0" @click="processedValue = false">
Expand Down Expand Up @@ -42,6 +42,15 @@

<Divider />

<div v-text="$i18n.t('settings.manage.heading')" />
<div class="-mt-2 text-sm leading-snug text-black text-opacity-75 dark:text-gray-50 dark:text-opacity-75" v-text="$i18n.t('settings.manage.description')" />
<div class="grid grid-flow-col grid-cols-2 gap-2 mt-1">
<ExportButton />
<ImportButton />
</div>

<Divider />

<SettingsCheck :settings-key="['reset']" />
</div>

Expand All @@ -60,7 +69,7 @@
<SettingsTime :settings-key="['schedule', 'lengths', 'work']" :min-ms="5000" />
<SettingsTime :settings-key="['schedule', 'lengths', 'shortpause']" :min-ms="5000" />
<SettingsTime :settings-key="['schedule', 'lengths', 'longpause']" :min-ms="5000" />
<div class="ring-inset ring ring-primary bg-primary/20 dark:bg-gray-700 dark:text-gray-100 flex flex-row items-center px-3 py-4 space-x-2 rounded-lg">
<div class="flex flex-row items-center px-3 py-4 space-x-2 rounded-lg ring-inset ring ring-primary bg-primary/20 dark:bg-gray-700 dark:text-gray-100">
<InfoIcon />
<span v-text="$i18n.t('settings.scheduleMinTime')" />
</div>
Expand Down Expand Up @@ -99,11 +108,11 @@
<div class="flex flex-col items-center justify-center mt-8">
<!-- Support links -->
<div class="flex flex-row mt-3 space-x-2 text-center">
<a href="https://www.github.com/Hanziness/AnotherPomodoro?utm_source=AnotherPomodoro&utm_medium=web&utm_content=settings" class="hover:bg-gray-700 active:bg-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600 dark:active:bg-gray-800 flex flex-row items-center px-4 py-2 space-x-1 text-white transition-colors bg-black rounded-full">
<a href="https://www.github.com/Hanziness/AnotherPomodoro?utm_source=AnotherPomodoro&utm_medium=web&utm_content=settings" class="flex flex-row items-center px-4 py-2 space-x-1 text-white transition-colors bg-black rounded-full hover:bg-gray-700 active:bg-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600 dark:active:bg-gray-800">
<AboutGithub />
<span v-text="$i18n.t('settings.about.source')" />
</a>
<a href="https://www.buymeacoffee.com/imreg?utm_source=AnotherPomodoro&utm_medium=web&utm_content=settings" class="hover:bg-yellow-200 active:bg-yellow-400 flex flex-row items-center px-4 py-2 space-x-1 text-black transition-colors bg-yellow-300 rounded-full">
<a href="https://www.buymeacoffee.com/imreg?utm_source=AnotherPomodoro&utm_medium=web&utm_content=settings" class="flex flex-row items-center px-4 py-2 space-x-1 text-black transition-colors bg-yellow-300 rounded-full hover:bg-yellow-200 active:bg-yellow-400">
<AboutSupport />
<span v-text="$i18n.t('settings.about.support')" />
</a>
Expand Down Expand Up @@ -161,6 +170,8 @@ import { XIcon, AdjustmentsIcon, AlarmIcon, ArtboardIcon, InfoCircleIcon, BrandG
import { mapActions, mapState, mapStores } from 'pinia'
import OptionGroup from '@/components/base/optionGroup.vue'
import TabHeader from '@/components/settings/panel/tabHeader.vue'
import ExportButton from '@/components/settings/exportButton.vue'
import ImportButton from '@/components/settings/importButton.vue'
import presetTimers from '@/assets/settings/timerPresets'
import { useSettings } from '~/stores/settings'
Expand All @@ -179,6 +190,8 @@ export default {
Divider: () => import(/* webpackMode: "eager" */ '@/components/base/divider.vue'),
OptionGroup,
TabHeader,
ExportButton,
ImportButton,
CloseIcon: XIcon,
// ResetIcon: RefreshAlertIcon,
TabIconGeneral: AdjustmentsIcon,
Expand Down
8 changes: 8 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@
"confirm": "Reset",
"cancel": "Cancel"
},
"manage": {
"heading": "Manage settings",
"description": "Download the current settings or load them from a file",
"buttons": {
"save": "Save",
"load": "Load"
}
},
"scheduleMinTime": "The minimum allowed time is 5 seconds",
"about": {
"madeby": "Made by Imre Gera",
Expand Down

0 comments on commit df3097b

Please sign in to comment.