diff --git a/src/annotations.js b/src/annotations.js index ff0ab8d5..e0699bf4 100644 --- a/src/annotations.js +++ b/src/annotations.js @@ -5,7 +5,7 @@ import GObject from 'gi://GObject' import { gettext as _, ngettext } from 'gettext' import * as utils from './utils.js' import * as CFI from './foliate-js/epubcfi.js' -import { vprintf } from './format.js' +import { vprintf, locales } from './format.js' const Bookmark = utils.makeDataClass('FoliateBookmark', { 'value': 'string', @@ -41,12 +41,22 @@ const BookmarkRow = GObject.registerClass({ } }) +const dateFormat = new Intl.DateTimeFormat(locales, { + year: 'numeric', month: 'short', day: 'numeric', + hour: 'numeric', minute: 'numeric', +}) + const AnnotationRow = GObject.registerClass({ GTypeName: 'FoliateAnnotationRow', Template: pkg.moduleuri('ui/annotation-row.ui'), - InternalChildren: ['heading', 'box', 'color', 'text', 'sep', 'note'], + Children: ['button'], + InternalChildren: ['heading', 'box', 'color', 'text', 'sep', 'note', 'bar', 'date'], + Properties: utils.makeParams({ + 'editable': 'boolean', + }), }, class extends Gtk.Box { update(obj) { + this.annotation = obj if (obj instanceof Annotation) { const { text, note, color } = obj this._text.label = text.trim().replace(/\n/g, ' ') @@ -57,6 +67,12 @@ const AnnotationRow = GObject.registerClass({ const showNote = Boolean(note) this._sep.visible = showNote this._note.visible = showNote + this._bar.show() + const date = obj.modified || obj.created + if (date) { + this._date.label = dateFormat.format(new Date(date)) + this._date.show() + } else this._date.hide() this.margin_top = 6 this.margin_bottom = 6 } else { @@ -65,6 +81,7 @@ const AnnotationRow = GObject.registerClass({ this._box.hide() this._sep.hide() this._note.hide() + this._bar.hide() this.margin_top = 3 this.margin_bottom = 3 } @@ -236,9 +253,11 @@ GObject.registerClass({ GTypeName: 'FoliateAnnotationView', Properties: utils.makeParams({ 'dir': 'string', + 'editable': 'boolean', }), Signals: { 'go-to-annotation': { param_types: [Annotation.$gtype] }, + 'delete-annotation': { param_types: [Annotation.$gtype] }, }, }, class extends Gtk.ListView { #filter @@ -251,8 +270,11 @@ GObject.registerClass({ const handlers = new WeakMap() this.factory = utils.connect(new Gtk.SignalListItemFactory(), { 'setup': (_, listItem) => { + const row = new AnnotationRow({ editable: this.editable }) + row.button.connect('clicked', () => + this.emit('delete-annotation', row.annotation)) listItem.child = new Gtk.TreeExpander({ indent_for_icon: false }) - listItem.child.child = new AnnotationRow() + listItem.child.child = row }, 'bind': (_, listItem) => { const expander = listItem.child diff --git a/src/app.js b/src/app.js index ae11394a..dfaa6022 100644 --- a/src/app.js +++ b/src/app.js @@ -284,7 +284,7 @@ export const Application = GObject.registerClass({ background-color: transparent; } .card-sidebar.flat-list .card { - padding: 12px; + padding: 6px 12px; } .book-image-frame { diff --git a/src/book-viewer.js b/src/book-viewer.js index c2cac571..456e4c54 100644 --- a/src/book-viewer.js +++ b/src/book-viewer.js @@ -733,6 +733,8 @@ export const BookViewer = GObject.registerClass({ this._view.showAnnotation(annotation) if (this._flap.collapsed) this._flap.show_sidebar = false }, + 'delete-annotation': (_, annotation) => + this.#deleteAnnotation(annotation), }) this._annotation_search_entry.connect('search-changed', entry => this._annotation_view.filter(entry.text)) @@ -902,18 +904,19 @@ export const BookViewer = GObject.registerClass({ this.#data.storage.set('lastLocation', cfi) } } + #deleteAnnotation(annotation) { + this.#data.deleteAnnotation(annotation) + this.root.add_toast(utils.connect(new Adw.Toast({ + title: _('Annotation deleted'), + button_label: _('Undo'), + }), { 'button-clicked': () => + this.#data.addAnnotation(annotation) })) + } #showSelection({ type, value, text, lang, pos: { point, dir } }) { if (type === 'annotation') return new Promise(resolve => { const annotation = this.#data.annotations.get(value) const popover = utils.connect(new AnnotationPopover({ annotation }), { - 'delete-annotation': () => { - this.#data.deleteAnnotation(annotation) - this.root.add_toast(utils.connect(new Adw.Toast({ - title: _('Annotation deleted'), - button_label: _('Undo'), - }), { 'button-clicked': () => - this.#data.addAnnotation(annotation) })) - }, + 'delete-annotation': () => this.#deleteAnnotation(annotation), 'select-annotation': () => resolve('select'), 'color-changed': (_, color) => this.highlight_color = color, }) diff --git a/src/format.js b/src/format.js index 98fe3900..e19a5f66 100644 --- a/src/format.js +++ b/src/format.js @@ -2,20 +2,28 @@ import GLib from 'gi://GLib' import Gio from 'gi://Gio' import { gettext as _ } from 'gettext' -const getCanonicalLocale = locale => { - try { return Intl.getCanonicalLocales(locale)[0] } +const makeLocale = locale => { + try { return new Intl.Locale(locale) } catch (e) { return null } } -const glibcLocaleToBCP47 = str => getCanonicalLocale( +const glibcLocale = str => makeLocale( str === 'C' ? 'en' : str.split('.')[0].replace('_', '-')) -export const locales = GLib.get_language_names().map(glibcLocaleToBCP47).filter(x => x) -try { - const settings = new Gio.Settings({ schema_id: 'org.gnome.system.locale' }) - const locale = glibcLocaleToBCP47(settings.get_string('region')) - if (locale) locales.unshift(locale) -} catch (e) {} +const getHourCycle = () => { + try { + const settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' }) + return settings.get_string('clock-format') === '24h' ? 'h23' : 'h12' + } catch (e) { + console.debug(e) + } +} + +const hourCycle = getHourCycle() + +export const locales = GLib.get_language_names() + .map(glibcLocale).filter(x => x) + .map(locale => new Intl.Locale(locale, { hourCycle })) const percentFormat = new Intl.NumberFormat(locales, { style: 'percent' }) export const percent = x => percentFormat.format(x) diff --git a/src/ui/annotation-row.ui b/src/ui/annotation-row.ui index ef2b1937..a85be007 100644 --- a/src/ui/annotation-row.ui +++ b/src/ui/annotation-row.ui @@ -44,5 +44,27 @@ + + + 12 + + + True + 0 + end + + + + + + + center + user-trash-symbolic + Delete + + + + + diff --git a/src/ui/book-viewer.ui b/src/ui/book-viewer.ui index 1ccd7f61..ecd31671 100644 --- a/src/ui/book-viewer.ui +++ b/src/ui/book-viewer.ui @@ -413,6 +413,7 @@ true + True True