/* * μlogger * * Copyright(C) 2019 Bartek Fabiszewski (www.fabiszewski.net) * * This is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import { auth, config, lang } from './constants.js'; import TrackDialog from './trackdialog.js'; import uAjax from './ajax.js'; import uEvent from './event.js'; import uList from './list.js'; import { uLogger } from './ulogger.js'; import uPosition from './position.js'; import uTrack from './track.js'; import uUtils from './utils.js'; /** * @class TrackList * @extends {uList} */ export default class TrackList extends uList { /** * @param {string} selector * @param {uBinder} binder */ constructor(selector, binder) { super(selector, binder, uTrack); if (binder) { this.binder.addEventListener(uEvent.EXPORT, this); this.binder.addEventListener(uEvent.IMPORT, this); } } /** * @override * @param {uTrack} row */ // eslint-disable-next-line class-methods-use-this updateDataRow(row) { row.user = uLogger.userList.current; } /** * @override * @param {(Event|uEvent)} event * @param {*=} data */ handleEvent(event, data) { if (event.type === uEvent.CHANGE) { config.showLatest = false; } super.handleEvent(event, data); if (event.type === uEvent.EXPORT) { this.current.export(data); } else if (event.type === uEvent.IMPORT) { this.import(data).catch((msg) => alert(`${lang.strings['actionfailure']}\n${msg}`)); } } /** * @param {HTMLFormElement} form * @return {Promise} */ import(form) { this.emit(true, 'import'); return uAjax.post('utils/import.php', form) .then((xml) => { const root = xml.getElementsByTagName('root'); const trackCnt = uUtils.getNodeAsInt(root[0], 'trackcnt'); if (trackCnt > 1) { alert(uUtils.sprintf(lang.strings['imultiple'], trackCnt)); } const trackId = uUtils.getNodeAsInt(root[0], 'trackid'); this.emit(false, 'import'); return this.fetch().then(() => this.select(trackId)); }).catch((msg) => { this.emit(false, 'import'); alert(`${lang.strings['actionfailure']}\n${msg}`); }); } emit(on, action) { this.binder.dispatchEvent(uEvent.LOADER, { on: on, action: action }); } /** * Fetch tracks for current user * @throws * @return {Promise} */ fetch() { this.emit(true, 'track'); return uAjax.get('utils/gettracks.php', { userid: uLogger.userList.current.id }) .then((xml) => { this.clear(); this.fromXml(xml.getElementsByTagName('track'), 'trackid', 'trackname'); this.emit(false, 'track'); return xml; }).catch((msg) => { this.emit(false, 'track'); alert(`${lang.strings['actionfailure']}\n${msg}`); }); } /** * Fetch track with latest position for current user * @throws * @return {Promise} */ fetchLatest() { this.emit(true, 'track'); const data = { last: 1 }; const allUsers = uLogger.userList.isSelectedAllOption; if (!allUsers) { data.userid = uLogger.userList.current.id; } return uAjax.get('utils/getpositions.php', data).then((xml) => { if (!allUsers) { const xmlPos = xml.getElementsByTagName('position'); // single user if (xmlPos.length === 1) { const position = uPosition.fromXml(xmlPos[0]); if (this.has(position.trackid)) { this.select(position.trackid, true); this.current.fromXml(xml, false); this.current.onlyLatest = true; this.current.render(); } else { // tracklist needs update return this.fetch().then(() => this.fetchLatest()); } } } else { // all users this.clear(); const track = new uTrack(0, '', null); track.binder = this.binder; track.continuous = false; track.fromXml(xml, false); this.add(track); this.select(0, true); this.current.render(); } this.emit(false, 'track'); return xml; }).catch((msg) => { this.emit(false, 'track'); alert(`${lang.strings['actionfailure']}\n${msg}`); }); } /** * @override */ onChange() { if (!config.showLatest) { this.fetchTrack(); } } /** * Fetch and render track */ fetchTrack() { if (this.current) { this.emit(true, 'track'); this.current.fetch() .then(() => this.emit(false, 'track')) .catch((msg) => { this.emit(false, 'track'); alert(`${lang.strings['actionfailure']}\n${msg}`); }); } } /** * @override */ onEdit() { if (this.current) { if (this.current.user.login !== auth.user.login && !auth.isAdmin) { alert(lang.strings['owntrackswarn']); return; } this.editTrack(); } } /** * @param {TrackDialog=} modal */ editTrack(modal) { const dialog = modal || new TrackDialog(this.current); dialog.show() .then((result) => { switch (result.action) { case 'update': this.current.name = result.data.name; return this.current.update('update').then(() => this.render()); case 'delete': return this.current.update('delete').then(() => this.remove(this.current.id)); default: break; } throw new Error(); }) .then(() => { alert(lang.strings['actionsuccess']); dialog.hide(); }) .catch((msg) => { alert(`${lang.strings['actionfailure']}\n${msg}`); this.editTrack(dialog); }); } /** * @override */ // eslint-disable-next-line no-empty-function,class-methods-use-this onAdd() { } }