Improve settings experience

old-stable24
Varun Patil 2022-10-24 18:58:49 -07:00
parent 7e48d06cc3
commit bcd8169d7f
3 changed files with 66 additions and 35 deletions

View File

@ -24,27 +24,27 @@
<div>
<label for="timeline-path">{{ t('memories', 'Timeline Path') }}</label>
<input id="timeline-path"
@click="chooseTimelinePath"
v-model="config_timelinePath"
type="text">
<label for="folders-path">{{ t('memories', 'Folders Path') }}</label>
<input id="folders-path"
@click="chooseFoldersPath"
v-model="config_foldersPath"
type="text">
<NcCheckboxRadioSwitch :checked.sync="config_showHidden"
@update:checked="updateShowHidden"
type="switch">
{{ t('memories', 'Show hidden folders') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch :checked.sync="config_squareThumbs"
@update:checked="updateSquareThumbs"
type="switch">
{{ t('memories', 'Square grid mode') }}
</NcCheckboxRadioSwitch>
<button @click="updateAll()">
{{ t('memories', 'Update') }}
</button>
</div>
</template>
@ -58,7 +58,7 @@ input[type=text] {
import { Component, Mixins } from 'vue-property-decorator';
import GlobalMixin from '../mixins/GlobalMixin';
import { showError } from '@nextcloud/dialogs'
import { getFilePickerBuilder } from '@nextcloud/dialogs'
import UserConfig from '../mixins/UserConfig'
import { NcCheckboxRadioSwitch } from '@nextcloud/vue'
@ -69,24 +69,42 @@ import { NcCheckboxRadioSwitch } from '@nextcloud/vue'
},
})
export default class Settings extends Mixins(UserConfig, GlobalMixin) {
async updateAll() {
// Update localStorage
localStorage.setItem('memories_squareThumbs', this.config_squareThumbs ? '1' : '0');
async chooseFolder(title: string, initial: string) {
const picker = getFilePickerBuilder(title)
.setMultiSelect(false)
.setModal(true)
.setType(1)
.addMimeTypeFilter('httpd/unix-directory')
.allowDirectories()
.startAt(initial)
.build()
// Settings list
const settings = ['showHidden', 'timelinePath', 'foldersPath'];
return await picker.pick();
}
// Update all
try {
const p = await Promise.all(settings.map(async (setting) => this.updateSetting(setting)));
if (p.some((r) => !r || r.status !== 200)) {
showError(this.t('memories', 'Error updating settings'));
} else {
window.location.reload();
async chooseTimelinePath() {
const newPath = await this.chooseFolder(this.t('memories', 'Choose the root of your timeline'), this.config_timelinePath);
if (newPath !== this.config_timelinePath) {
this.config_timelinePath = newPath;
await this.updateSetting('timelinePath');
}
} catch (e) {
showError(e?.response?.data?.message || this.t('memories', 'Error updating settings'));
}
async chooseFoldersPath() {
const newPath = await this.chooseFolder(this.t('memories', 'Choose the root for the folders view'), this.config_foldersPath);
if (newPath !== this.config_foldersPath) {
this.config_foldersPath = newPath;
await this.updateSetting('foldersPath');
}
}
async updateSquareThumbs() {
console.error('updateSquareThumbs', this.config_squareThumbs);
await this.updateSetting('squareThumbs');
}
async updateShowHidden() {
await this.updateSetting('showHidden');
}
}
</script>

View File

@ -104,6 +104,7 @@ import { IDay, IFolder, IHeadRow, IPhoto, IRow, IRowType } from "../types";
import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
import { NcEmptyContent } from '@nextcloud/vue';
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import GlobalMixin from '../mixins/GlobalMixin';
import UserConfig from "../mixins/UserConfig";
@ -153,8 +154,6 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
private list: IRow[] = [];
/** Computed number of columns */
private numCols = 0;
/** Keep all images square */
private squareMode = false;
/** Header rows for dayId key */
private heads: { [dayid: number]: IHeadRow } = {};
@ -208,10 +207,12 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
}
beforeDestroy() {
unsubscribe(this.config_eventName, this.refresh);
this.resetState();
}
created() {
subscribe(this.config_eventName, this.refresh);
window.addEventListener("resize", this.handleResizeWithDelay);
}
@ -326,12 +327,9 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
// Mobile
this.numCols = MOBILE_NUM_COLS;
this.rowHeight = Math.floor(this.rowWidth / this.numCols);
this.squareMode = true;
} else {
// Desktop
this.squareMode = this.config_squareThumbs;
if (this.squareMode) {
if (this.config_squareThumbs) {
// Set columns first, then height
this.numCols = Math.max(3, Math.floor(this.rowWidth / DESKTOP_ROW_HEIGHT));
this.rowHeight = Math.floor(this.rowWidth / this.numCols);
@ -814,6 +812,9 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
row.photos = [];
}
// Force all to square
const squareMode = this.isMobile() || this.config_squareThumbs;
// Create justified layout with correct params
const justify = getLayout(day.detail.map(p => {
return {
@ -824,7 +825,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
}), {
rowWidth: this.rowWidth,
rowHeight: this.rowHeight,
squareMode: this.squareMode,
squareMode: squareMode,
numCols: this.numCols,
allowBreakout: this.allowBreakout(),
seed: dayId,
@ -900,7 +901,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
const setPos = () => {
photo.dispW = utils.roundHalf(jbox.width);
photo.dispX = utils.roundHalf(jbox.left);
photo.dispH = this.squareMode ? utils.roundHalf(jbox.height) : 0;
photo.dispH = squareMode ? utils.roundHalf(jbox.height) : 0;
photo.dispY = 0;
photo.dispRowNum = row.num;
};

View File

@ -27,6 +27,7 @@ import { loadState } from '@nextcloud/initial-state'
import axios from '@nextcloud/axios'
const eventName = 'memories:user-config-changed'
const localSettings = ['squareThumbs', 'showFaceRect'];
@Component
export default class UserConfig extends Vue {
@ -39,6 +40,8 @@ export default class UserConfig extends Vue {
config_squareThumbs = localStorage.getItem('memories_squareThumbs') === '1';
config_showFaceRect = localStorage.getItem('memories_showFaceRect') === '1';
config_eventName = eventName;
created() {
subscribe(eventName, this.updateLocalSetting)
}
@ -48,17 +51,26 @@ export default class UserConfig extends Vue {
}
updateLocalSetting({ setting, value }) {
this[setting] = value
this['config_' + setting] = value
}
async updateSetting(setting: string) {
const value = this['config_' + setting]
if (localSettings.includes(setting)) {
if (typeof value === 'boolean') {
localStorage.setItem('memories_' + setting, value ? '1' : '0')
} else {
localStorage.setItem('memories_' + setting, value)
}
} else {
// Long time save setting
const res = await axios.put(generateUrl('apps/memories/api/config/' + setting), {
await axios.put(generateUrl('apps/memories/api/config/' + setting), {
value: value.toString(),
})
});
}
// Visible elements update setting
emit(eventName, { setting, value })
return res;
emit(eventName, { setting, value });
}
}