Fix custom quotes saving issue, fix viewport width
This commit is contained in:
250
prefs.js
250
prefs.js
@ -61,7 +61,6 @@ export default class QuotesPreferences extends ExtensionPreferences {
|
||||
// API URL
|
||||
const apiRow = new Adw.EntryRow({
|
||||
title: 'API URL',
|
||||
subtitle: 'URL for fetching quotes from remote server',
|
||||
text: settings.get_string('api-url'),
|
||||
});
|
||||
apiGroup.add(apiRow);
|
||||
@ -96,7 +95,6 @@ export default class QuotesPreferences extends ExtensionPreferences {
|
||||
// Text color
|
||||
const colorRow = new Adw.EntryRow({
|
||||
title: 'Text Color',
|
||||
subtitle: 'Color for quote text in hex format',
|
||||
text: settings.get_string('text-color'),
|
||||
});
|
||||
displayGroup.add(colorRow);
|
||||
@ -131,7 +129,6 @@ export default class QuotesPreferences extends ExtensionPreferences {
|
||||
// Quotes file
|
||||
const quotesFileRow = new Adw.EntryRow({
|
||||
title: 'Quotes File Name',
|
||||
subtitle: 'JSON file name for storing quotes',
|
||||
text: settings.get_string('quotes-file'),
|
||||
});
|
||||
storageGroup.add(quotesFileRow);
|
||||
@ -144,61 +141,250 @@ export default class QuotesPreferences extends ExtensionPreferences {
|
||||
window.add(quotesPage);
|
||||
|
||||
const quotesSourceGroup = new Adw.PreferencesGroup({
|
||||
title: 'Quote Source',
|
||||
description: 'Choose between built-in/synced quotes or custom quotes',
|
||||
title: 'Quote Priority',
|
||||
description: 'Custom quotes and synced quotes are both saved to the JSON file',
|
||||
});
|
||||
quotesPage.add(quotesSourceGroup);
|
||||
|
||||
// Use custom quotes switch
|
||||
const useCustomQuotesRow = new Adw.SwitchRow({
|
||||
title: 'Use Custom Quotes',
|
||||
subtitle: 'Use custom quotes instead of built-in/synced quotes',
|
||||
title: 'Prioritize Custom Quotes',
|
||||
active: settings.get_boolean('use-custom-quotes'),
|
||||
});
|
||||
quotesSourceGroup.add(useCustomQuotesRow);
|
||||
|
||||
const customQuotesGroup = new Adw.PreferencesGroup({
|
||||
title: 'Custom Quotes',
|
||||
description: 'Edit your custom quotes in JSON format',
|
||||
description: 'Manage your custom quotes with an easy-to-use interface.',
|
||||
});
|
||||
quotesPage.add(customQuotesGroup);
|
||||
|
||||
// Custom quotes text area
|
||||
const quotesTextView = new Gtk.TextView({
|
||||
editable: true,
|
||||
wrap_mode: Gtk.WrapMode.WORD,
|
||||
hexpand: true,
|
||||
vexpand: true,
|
||||
});
|
||||
|
||||
const quotesBuffer = quotesTextView.get_buffer();
|
||||
const customQuotesText = settings.get_string('custom-quotes');
|
||||
|
||||
// Parse existing custom quotes
|
||||
let customQuotesArray = [];
|
||||
try {
|
||||
const quotesArray = JSON.parse(customQuotesText);
|
||||
quotesBuffer.set_text(JSON.stringify(quotesArray, null, 2), -1);
|
||||
customQuotesArray = JSON.parse(settings.get_string('custom-quotes'));
|
||||
} catch (e) {
|
||||
quotesBuffer.set_text('[\n {\n "text": "Your custom quote here",\n "author": "Author Name"\n }\n]', -1);
|
||||
customQuotesArray = [];
|
||||
}
|
||||
|
||||
// Create list box for quotes
|
||||
const quotesListBox = new Gtk.ListBox({
|
||||
selection_mode: Gtk.SelectionMode.SINGLE,
|
||||
hexpand: true,
|
||||
margin_top: 12,
|
||||
margin_bottom: 12,
|
||||
margin_start: 12,
|
||||
margin_end: 12,
|
||||
css_classes: ['boxed-list'],
|
||||
});
|
||||
|
||||
// Function to create quote row
|
||||
const createQuoteRow = (quote, index) => {
|
||||
const row = new Gtk.ListBoxRow();
|
||||
const box = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 6,
|
||||
margin_top: 12,
|
||||
margin_bottom: 12,
|
||||
margin_start: 12,
|
||||
margin_end: 12,
|
||||
});
|
||||
|
||||
const quoteLabel = new Gtk.Label({
|
||||
label: `"${quote.text}"`,
|
||||
wrap: true,
|
||||
xalign: 0,
|
||||
css_classes: ['title-4'],
|
||||
});
|
||||
|
||||
const authorLabel = new Gtk.Label({
|
||||
label: `— ${quote.author}`,
|
||||
xalign: 0,
|
||||
css_classes: ['dim-label'],
|
||||
});
|
||||
|
||||
box.append(quoteLabel);
|
||||
box.append(authorLabel);
|
||||
row.set_child(box);
|
||||
row._quoteIndex = index;
|
||||
return row;
|
||||
};
|
||||
|
||||
// Populate list with existing quotes
|
||||
const refreshQuotesList = () => {
|
||||
const child = quotesListBox.get_first_child();
|
||||
while (child) {
|
||||
const next = child.get_next_sibling();
|
||||
quotesListBox.remove(child);
|
||||
child = next;
|
||||
}
|
||||
|
||||
customQuotesArray.forEach((quote, index) => {
|
||||
quotesListBox.append(createQuoteRow(quote, index));
|
||||
});
|
||||
};
|
||||
|
||||
refreshQuotesList();
|
||||
|
||||
// Buttons container
|
||||
const buttonsBox = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.HORIZONTAL,
|
||||
spacing: 12,
|
||||
margin_top: 12,
|
||||
halign: Gtk.Align.END,
|
||||
});
|
||||
|
||||
// Add button
|
||||
const addButton = new Gtk.Button({
|
||||
label: 'Add Quote',
|
||||
css_classes: ['suggested-action'],
|
||||
});
|
||||
|
||||
// Edit button
|
||||
const editButton = new Gtk.Button({
|
||||
label: 'Edit',
|
||||
sensitive: false,
|
||||
});
|
||||
|
||||
// Remove button
|
||||
const removeButton = new Gtk.Button({
|
||||
label: 'Remove',
|
||||
css_classes: ['destructive-action'],
|
||||
sensitive: false,
|
||||
});
|
||||
|
||||
buttonsBox.append(addButton);
|
||||
buttonsBox.append(editButton);
|
||||
buttonsBox.append(removeButton);
|
||||
|
||||
// Main container
|
||||
const quotesContainer = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 12,
|
||||
});
|
||||
|
||||
const scrolledWindow = new Gtk.ScrolledWindow({
|
||||
child: quotesTextView,
|
||||
child: quotesListBox,
|
||||
hexpand: true,
|
||||
vexpand: true,
|
||||
min_content_height: 200,
|
||||
max_content_height: 300,
|
||||
});
|
||||
|
||||
quotesContainer.append(scrolledWindow);
|
||||
quotesContainer.append(buttonsBox);
|
||||
|
||||
const quotesExpander = new Adw.ExpanderRow({
|
||||
title: 'Custom Quotes Editor',
|
||||
subtitle: 'JSON format: [{"text": "quote", "author": "author"}]',
|
||||
title: 'Custom Quotes Manager',
|
||||
});
|
||||
|
||||
quotesExpander.add_row(new Adw.PreferencesRow({
|
||||
child: scrolledWindow,
|
||||
child: quotesContainer,
|
||||
}));
|
||||
|
||||
customQuotesGroup.add(quotesExpander);
|
||||
|
||||
// Handle list selection
|
||||
quotesListBox.connect('row-selected', (listbox, row) => {
|
||||
const hasSelection = row !== null;
|
||||
editButton.sensitive = hasSelection;
|
||||
removeButton.sensitive = hasSelection;
|
||||
});
|
||||
|
||||
// Quote dialog function
|
||||
const showQuoteDialog = (quote = null, index = -1) => {
|
||||
const dialog = new Gtk.Dialog({
|
||||
title: quote ? 'Edit Quote' : 'Add Quote',
|
||||
modal: true,
|
||||
transient_for: window,
|
||||
});
|
||||
|
||||
dialog.add_button('Cancel', Gtk.ResponseType.CANCEL);
|
||||
dialog.add_button(quote ? 'Save' : 'Add', Gtk.ResponseType.OK);
|
||||
|
||||
const contentArea = dialog.get_content_area();
|
||||
contentArea.set_spacing(12);
|
||||
contentArea.set_margin_top(12);
|
||||
contentArea.set_margin_bottom(12);
|
||||
contentArea.set_margin_start(12);
|
||||
contentArea.set_margin_end(12);
|
||||
|
||||
const textEntry = new Gtk.Entry({
|
||||
placeholder_text: 'Enter quote text...',
|
||||
text: quote ? quote.text : '',
|
||||
hexpand: true,
|
||||
});
|
||||
|
||||
const authorEntry = new Gtk.Entry({
|
||||
placeholder_text: 'Enter author name...',
|
||||
text: quote ? quote.author : '',
|
||||
hexpand: true,
|
||||
});
|
||||
|
||||
const textLabel = new Gtk.Label({
|
||||
label: 'Quote Text:',
|
||||
xalign: 0,
|
||||
});
|
||||
|
||||
const authorLabel = new Gtk.Label({
|
||||
label: 'Author:',
|
||||
xalign: 0,
|
||||
});
|
||||
|
||||
contentArea.append(textLabel);
|
||||
contentArea.append(textEntry);
|
||||
contentArea.append(authorLabel);
|
||||
contentArea.append(authorEntry);
|
||||
|
||||
dialog.connect('response', (dialog, response) => {
|
||||
if (response === Gtk.ResponseType.OK) {
|
||||
const text = textEntry.get_text().trim();
|
||||
const author = authorEntry.get_text().trim();
|
||||
|
||||
if (text && author) {
|
||||
const newQuote = { text, author };
|
||||
|
||||
if (index >= 0) {
|
||||
customQuotesArray[index] = newQuote;
|
||||
} else {
|
||||
customQuotesArray.push(newQuote);
|
||||
}
|
||||
|
||||
settings.set_string('custom-quotes', JSON.stringify(customQuotesArray));
|
||||
refreshQuotesList();
|
||||
}
|
||||
}
|
||||
dialog.destroy();
|
||||
});
|
||||
|
||||
dialog.present();
|
||||
};
|
||||
|
||||
// Button handlers
|
||||
addButton.connect('clicked', () => {
|
||||
showQuoteDialog();
|
||||
});
|
||||
|
||||
editButton.connect('clicked', () => {
|
||||
const selectedRow = quotesListBox.get_selected_row();
|
||||
if (selectedRow) {
|
||||
const index = selectedRow._quoteIndex;
|
||||
showQuoteDialog(customQuotesArray[index], index);
|
||||
}
|
||||
});
|
||||
|
||||
removeButton.connect('clicked', () => {
|
||||
const selectedRow = quotesListBox.get_selected_row();
|
||||
if (selectedRow) {
|
||||
const index = selectedRow._quoteIndex;
|
||||
customQuotesArray.splice(index, 1);
|
||||
settings.set_string('custom-quotes', JSON.stringify(customQuotesArray));
|
||||
refreshQuotesList();
|
||||
editButton.sensitive = false;
|
||||
removeButton.sensitive = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Bind settings
|
||||
settings.bind(
|
||||
'rotation-interval',
|
||||
@ -256,17 +442,5 @@ export default class QuotesPreferences extends ExtensionPreferences {
|
||||
Gio.SettingsBindFlags.DEFAULT
|
||||
);
|
||||
|
||||
// Save custom quotes when text changes
|
||||
quotesBuffer.connect('changed', () => {
|
||||
const [start, end] = quotesBuffer.get_bounds();
|
||||
const text = quotesBuffer.get_text(start, end, false);
|
||||
try {
|
||||
// Validate JSON
|
||||
JSON.parse(text);
|
||||
settings.set_string('custom-quotes', text);
|
||||
} catch (e) {
|
||||
// Invalid JSON, don't save
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user