mirror of
https://github.com/edu4rdshl/Strata.git
synced 2026-07-17 23:24:46 +00:00
style: conform the extension to the GJS ESLint config
- clipboardItem: convert _init() to constructor()/super() and give the class
an explicit GTypeName (no-restricted-syntax, no-shadow).
- clipboardItem: replace new URL() with GLib.Uri.parse().get_host(). GJS has
no global URL, so the old call always threw and the URL hostname subtitle
never rendered; this makes it work.
- Use optional catch bindings (catch {}); logError guards with
instanceof GLib.Error instead of a try/catch.
- prefs: drop an unused GLib import.
- panel: block-body promise executors, and a no-await-in-loop disable on the
batched renders (the per-batch yield is intentional).
- Drop the remaining restate-the-code comments.
This commit is contained in:
parent
376c6442f9
commit
bb792cee95
4 changed files with 28 additions and 50 deletions
|
|
@ -15,9 +15,8 @@ import { StrataProxy, BUS_NAME, OBJECT_PATH } from './dbus.js';
|
|||
import { StrataPanel } from './ui/panel.js';
|
||||
|
||||
function logError(label, err) {
|
||||
if (err !== undefined) {
|
||||
try { Gio.DBusError.strip_remote_error(err); } catch (_) {}
|
||||
}
|
||||
if (err instanceof GLib.Error)
|
||||
Gio.DBusError.strip_remote_error(err);
|
||||
const tail = err !== undefined ? `: ${err?.message ?? err}` : '';
|
||||
console.error(`[Strata] ${label}${tail}`);
|
||||
}
|
||||
|
|
@ -110,7 +109,6 @@ export default class StrataExtension extends Extension {
|
|||
GLib.Source.remove(this._daemonRestartTimerId);
|
||||
this._daemonRestartTimerId = null;
|
||||
}
|
||||
// Clean up in reverse order.
|
||||
this._unregisterShortcut();
|
||||
this._disconnectClipboardMonitor();
|
||||
this._disconnectFocusTracking();
|
||||
|
|
@ -235,7 +233,6 @@ export default class StrataExtension extends Extension {
|
|||
/** Pick the best MIME type to store from the offered list (mirrors Rust pick_mime). */
|
||||
_pickMime(mimes) {
|
||||
const PREFERRED = [
|
||||
// Raster images (size-capped at MAX_IMAGE).
|
||||
'image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp',
|
||||
'image/bmp', 'image/tiff', 'image/x-icon',
|
||||
// Plain text (UTF-8 preferred, then locale, then X11 legacy aliases).
|
||||
|
|
@ -281,7 +278,7 @@ export default class StrataExtension extends Extension {
|
|||
try {
|
||||
_conn.call_finish(result);
|
||||
// Name already owned (e.g. systemd user service) - don't spawn a second instance.
|
||||
} catch (_) {
|
||||
} catch {
|
||||
this._doSpawnDaemon();
|
||||
}
|
||||
}
|
||||
|
|
@ -324,7 +321,7 @@ export default class StrataExtension extends Extension {
|
|||
urgency: MessageTray.Urgency.HIGH,
|
||||
});
|
||||
source.addNotification(notification);
|
||||
} catch (_) {
|
||||
} catch {
|
||||
// Message tray may not be available (e.g. during early startup) - already logged above.
|
||||
}
|
||||
}
|
||||
|
|
@ -373,12 +370,12 @@ export default class StrataExtension extends Extension {
|
|||
try {
|
||||
// Graceful shutdown via D-Bus first.
|
||||
this._proxy?.ShutdownRemote(() => {});
|
||||
} catch (_) {}
|
||||
} catch { /* proxy may already be gone */ }
|
||||
// Give it 1.5s then force-terminate. Track the source so a re-enable
|
||||
// within that window can cancel it (see enable()).
|
||||
this._daemonKillTimerId = GLib.timeout_add(GLib.PRIORITY_LOW, 1500, () => {
|
||||
this._daemonKillTimerId = null;
|
||||
try { daemonToStop.send_signal(15); } catch (_) {} // SIGTERM
|
||||
try { daemonToStop.send_signal(15); } catch { /* already exited */ } // SIGTERM
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
}
|
||||
|
|
@ -440,7 +437,7 @@ export default class StrataExtension extends Extension {
|
|||
const cachePath =
|
||||
`${GLib.get_user_cache_dir()}/strata/thumbnails/${id}.png`;
|
||||
GLib.unlink(cachePath);
|
||||
} catch (_) {}
|
||||
} catch { /* no cached thumbnail for this id */ }
|
||||
this._addIdleSource(() => this._panel?.removeItem(id));
|
||||
});
|
||||
|
||||
|
|
@ -454,7 +451,7 @@ export default class StrataExtension extends Extension {
|
|||
'standard::name', Gio.FileQueryInfoFlags.NONE, null);
|
||||
let info;
|
||||
while ((info = en.next_file(null))) {
|
||||
try { d.get_child(info.get_name()).delete(null); } catch (_) {}
|
||||
try { d.get_child(info.get_name()).delete(null); } catch { /* best-effort cleanup */ }
|
||||
}
|
||||
en.close(null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
import Adw from 'gi://Adw';
|
||||
import Gtk from 'gi://Gtk';
|
||||
import Gdk from 'gi://Gdk';
|
||||
import GLib from 'gi://GLib';
|
||||
import Gio from 'gi://Gio';
|
||||
|
||||
import { ExtensionPreferences } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
|
||||
|
|
@ -211,7 +210,6 @@ export default class StrataPreferences extends ExtensionPreferences {
|
|||
for (const app of currentApps)
|
||||
model.append(app);
|
||||
|
||||
/** Sync the StringList back to GSettings. */
|
||||
const saveModel = () => {
|
||||
const apps = [];
|
||||
for (let i = 0; i < model.get_n_items(); i++) {
|
||||
|
|
|
|||
|
|
@ -22,24 +22,23 @@ function iconForMime(mimeType) {
|
|||
return 'edit-copy-symbolic';
|
||||
}
|
||||
|
||||
/** Detect if a string looks like a URL. */
|
||||
function isUrl(text) {
|
||||
return /^https?:\/\/.+/i.test(text.trim());
|
||||
}
|
||||
|
||||
/** Detect if a string looks like a CSS/hex color. */
|
||||
function isColor(text) {
|
||||
return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(text.trim());
|
||||
}
|
||||
|
||||
export const ClipboardItem = GObject.registerClass({
|
||||
GTypeName: 'StrataClipboardItem',
|
||||
Signals: {
|
||||
'activate': {},
|
||||
'delete': {},
|
||||
},
|
||||
}, class ClipboardItem extends St.Button {
|
||||
_init(id, mimeType, preview, opts = {}) {
|
||||
super._init({
|
||||
}, class extends St.Button {
|
||||
constructor(id, mimeType, preview, opts = {}) {
|
||||
super({
|
||||
style_class: 'strata-item',
|
||||
x_expand: true,
|
||||
can_focus: true,
|
||||
|
|
@ -56,13 +55,9 @@ export const ClipboardItem = GObject.registerClass({
|
|||
x_expand: true,
|
||||
});
|
||||
|
||||
// Left: icon or image thumbnail
|
||||
row.add_child(this._buildLeading(mimeType, preview));
|
||||
|
||||
// Center: text preview
|
||||
row.add_child(this._buildContent(mimeType, preview));
|
||||
|
||||
// Right: delete button
|
||||
const deleteBtn = new St.Button({
|
||||
style_class: 'strata-item-delete',
|
||||
icon_name: 'edit-delete-symbolic',
|
||||
|
|
@ -122,7 +117,7 @@ export const ClipboardItem = GObject.registerClass({
|
|||
const applyStyle = () => {
|
||||
try {
|
||||
container.style = `background-image: url("${fileUri}"); background-size: cover; background-repeat: no-repeat;`;
|
||||
} catch (_) { /* container was destroyed mid-flight */ }
|
||||
} catch { /* container was destroyed mid-flight */ }
|
||||
};
|
||||
|
||||
try {
|
||||
|
|
@ -187,7 +182,7 @@ export const ClipboardItem = GObject.registerClass({
|
|||
x_align: Clutter.ActorAlign.CENTER,
|
||||
});
|
||||
container.add_child(icon);
|
||||
} catch (_) {}
|
||||
} catch { /* container destroyed before the icon was added */ }
|
||||
}
|
||||
|
||||
_buildColorSwatch(hex) {
|
||||
|
|
@ -208,7 +203,7 @@ export const ClipboardItem = GObject.registerClass({
|
|||
style_class: 'strata-item-content',
|
||||
});
|
||||
|
||||
let mainText = '';
|
||||
let mainText;
|
||||
let subText = '';
|
||||
|
||||
if (mimeType.startsWith('image/')) {
|
||||
|
|
@ -219,8 +214,8 @@ export const ClipboardItem = GObject.registerClass({
|
|||
} else if (isUrl(preview)) {
|
||||
mainText = preview.trim();
|
||||
try {
|
||||
subText = new URL(preview.trim()).hostname;
|
||||
} catch (_) {}
|
||||
subText = GLib.Uri.parse(preview.trim(), GLib.UriFlags.NONE).get_host() ?? '';
|
||||
} catch { /* not a parseable URI */ }
|
||||
} else if (isColor(preview)) {
|
||||
mainText = preview.trim().toUpperCase();
|
||||
subText = 'Color';
|
||||
|
|
|
|||
|
|
@ -14,9 +14,8 @@ const SEARCH_DEBOUNCE_MS = 150;
|
|||
const LOAD_MORE_THRESHOLD = 200;
|
||||
|
||||
function logError(label, err) {
|
||||
if (err !== undefined) {
|
||||
try { Gio.DBusError.strip_remote_error(err); } catch (_) {}
|
||||
}
|
||||
if (err instanceof GLib.Error)
|
||||
Gio.DBusError.strip_remote_error(err);
|
||||
const tail = err !== undefined ? `: ${err?.message ?? err}` : '';
|
||||
console.error(`[Strata] ${label}${tail}`);
|
||||
}
|
||||
|
|
@ -83,7 +82,6 @@ export class StrataPanel {
|
|||
return this._interfaceSettings.get_string('color-scheme') !== 'prefer-dark';
|
||||
}
|
||||
|
||||
/** Toggle the light-theme class on the panel root box. */
|
||||
_applyTheme() {
|
||||
if (!this._box) return;
|
||||
if (this._effectiveIsLight())
|
||||
|
|
@ -103,7 +101,6 @@ export class StrataPanel {
|
|||
|
||||
|
||||
_buildUI() {
|
||||
// Overlay container - sits above all windows.
|
||||
this._overlay = new St.Widget({
|
||||
layout_manager: new Clutter.FixedLayout(),
|
||||
visible: false,
|
||||
|
|
@ -190,7 +187,6 @@ export class StrataPanel {
|
|||
this._searchEntry.get_clutter_text().connect('text-changed', () => {
|
||||
this._scheduleSearch(this._searchEntry.get_text());
|
||||
});
|
||||
// Down arrow from search box moves focus to the first item.
|
||||
this._searchEntry.get_clutter_text().connect('key-press-event', (_actor, event) => {
|
||||
if (event.get_key_symbol() === Clutter.KEY_Down) {
|
||||
this._focusItem(0);
|
||||
|
|
@ -212,11 +208,9 @@ export class StrataPanel {
|
|||
});
|
||||
this._scrollView.set_child(this._itemList);
|
||||
|
||||
// Load more items when scrolled near the bottom.
|
||||
const vadj = this._scrollView.get_vadjustment();
|
||||
if (vadj) {
|
||||
vadj.connect('notify::value', () => this._maybeLoadMore());
|
||||
// Also re-check when the list grows (a new page just appended).
|
||||
vadj.connect('notify::upper', () => this._maybeLoadMore());
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +265,6 @@ export class StrataPanel {
|
|||
close() {
|
||||
if (!this._visible) return;
|
||||
this._visible = false;
|
||||
// Clear hover state since the panel is closing.
|
||||
this._hoveredWidget?.remove_style_class_name('strata-item-hovered');
|
||||
this._hoveredWidget = null;
|
||||
if (this._grab) {
|
||||
|
|
@ -293,7 +286,6 @@ export class StrataPanel {
|
|||
this._widgets.delete(id);
|
||||
}
|
||||
|
||||
// While searching, only render if the new item matches the active query.
|
||||
if (this._searchQuery && !this._matchesSearch(preview, mimeType)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -337,7 +329,6 @@ export class StrataPanel {
|
|||
if (wasHovered) this._hoveredWidget = null;
|
||||
widget.destroy();
|
||||
this._widgets.delete(id);
|
||||
// Re-assign active to the new first visible item.
|
||||
if (wasActive) {
|
||||
const first = this._getVisibleItems()[0];
|
||||
if (first) this._setActiveWidget(first);
|
||||
|
|
@ -395,14 +386,15 @@ export class StrataPanel {
|
|||
const BATCH = 20;
|
||||
for (let i = 0; i < items.length; i += BATCH) {
|
||||
if (!this._overlay) return false;
|
||||
await new Promise(resolve =>
|
||||
// eslint-disable-next-line no-await-in-loop -- batches deliberately yield to the main loop
|
||||
await new Promise(resolve => {
|
||||
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
||||
const end = Math.min(i + BATCH, items.length);
|
||||
for (let j = i; j < end; j++) this._appendItemFromMeta(items[j]);
|
||||
resolve();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
this._loadedOffset = offset + items.length;
|
||||
this._hasMore = items.length >= limit;
|
||||
|
|
@ -445,7 +437,6 @@ export class StrataPanel {
|
|||
// snapshot (no re-query, so a scroll cannot race the search).
|
||||
this._renderSearchPage(this._searchEpoch);
|
||||
} else {
|
||||
// Browse mode: pull the next page from the daemon.
|
||||
if (!this._hasMore) return;
|
||||
this._loadingMore = true;
|
||||
this._loadHistory(this._loadedOffset, this._pageSize)
|
||||
|
|
@ -482,12 +473,14 @@ export class StrataPanel {
|
|||
if (i === 0) {
|
||||
renderChunk();
|
||||
} else {
|
||||
await new Promise(resolve =>
|
||||
// eslint-disable-next-line no-await-in-loop -- batches deliberately yield to the main loop
|
||||
await new Promise(resolve => {
|
||||
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
||||
renderChunk();
|
||||
resolve();
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
this._searchRendered = end;
|
||||
|
|
@ -543,14 +536,12 @@ export class StrataPanel {
|
|||
return widget;
|
||||
}
|
||||
|
||||
/** Focus the item at visible-list index `idx` (clamped). */
|
||||
_focusItem(idx) {
|
||||
const items = this._getVisibleItems();
|
||||
if (items.length === 0) return;
|
||||
global.stage.set_key_focus(items[Math.max(0, Math.min(idx, items.length - 1))]);
|
||||
}
|
||||
|
||||
/** All currently-visible item actors in order. */
|
||||
_getVisibleItems() {
|
||||
return this._itemList.get_children().filter(c => c.visible);
|
||||
}
|
||||
|
|
@ -717,13 +708,11 @@ export class StrataPanel {
|
|||
}
|
||||
|
||||
_moveItemToTop(id, widget) {
|
||||
// Move data model entry to front.
|
||||
const idx = this._items.findIndex(i => i.id === id);
|
||||
if (idx > 0) {
|
||||
const [entry] = this._items.splice(idx, 1);
|
||||
this._items.unshift(entry);
|
||||
}
|
||||
// Move actor to position 0 in the list.
|
||||
this._itemList.set_child_at_index(widget, 0);
|
||||
}
|
||||
|
||||
|
|
@ -750,7 +739,6 @@ export class StrataPanel {
|
|||
const MARGIN = 16; // px gap from screen edge
|
||||
|
||||
let x, y;
|
||||
// Horizontal
|
||||
if (position.endsWith('left'))
|
||||
x = monitor.x + MARGIN;
|
||||
else if (position.endsWith('right'))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue