Settings module for Text Explainer
Tính đến
Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta
// @require https://update.greasyfork.org/scripts/528763/1547018/Text%20Explainer%20Settings.js
// ==UserScript==
// @name Text Explainer Settings
// @namespace http://tampermonkey.net/
// @version 0.1.0
// @description Settings module for Text Explainer
// @author RoCry
// @license MIT
// ==/UserScript==
class TextExplainerSettings {
constructor(defaultConfig = {}) {
this.defaultConfig = Object.assign({
model: "gemini-2.0-flash",
apiKey: null,
baseUrl: "https://generativelanguage.googleapis.com",
provider: "gemini",
language: "Chinese"
}, defaultConfig);
this.config = this.load();
}
/**
* Load settings from storage
*/
load() {
try {
const savedConfig = typeof GM_getValue === 'function'
? GM_getValue('explainerConfig', {})
: JSON.parse(localStorage.getItem('explainerConfig') || '{}');
return Object.assign({}, this.defaultConfig, savedConfig);
} catch (e) {
console.error('Error loading settings:', e);
return Object.assign({}, this.defaultConfig);
}
}
/**
* Save settings to storage
*/
save() {
try {
if (typeof GM_setValue === 'function') {
GM_setValue('explainerConfig', this.config);
} else {
localStorage.setItem('explainerConfig', JSON.stringify(this.config));
}
return true;
} catch (e) {
console.error('Error saving settings:', e);
return false;
}
}
/**
* Get setting value
*/
get(key) {
return this.config[key];
}
/**
* Set setting value
*/
set(key, value) {
this.config[key] = value;
return this;
}
/**
* Update multiple settings at once
*/
update(settings) {
Object.assign(this.config, settings);
return this;
}
/**
* Reset settings to defaults
*/
reset() {
this.config = Object.assign({}, this.defaultConfig);
return this;
}
/**
* Get all settings
*/
getAll() {
return Object.assign({}, this.config);
}
/**
* Open settings dialog
*/
openDialog(onSave = null) {
// First check if dialog already exists and remove it
const existingDialog = document.getElementById('explainer-settings-dialog');
if (existingDialog) existingDialog.remove();
// Create dialog container
const dialog = document.createElement('div');
dialog.id = 'explainer-settings-dialog';
dialog.style = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 16px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
z-index: 10001;
width: 400px;
max-width: 90vw;
font-family: system-ui, sans-serif;
`;
// Add dark mode support
const styleElement = document.createElement('style');
styleElement.textContent = `
#explainer-settings-dialog {
color: #333;
}
#explainer-settings-dialog label {
display: block;
margin: 12px 0 4px;
font-weight: 500;
}
#explainer-settings-dialog input[type="text"],
#explainer-settings-dialog select {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
font-size: 14px;
}
#explainer-settings-dialog .buttons {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 20px;
}
#explainer-settings-dialog button {
padding: 8px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
#explainer-settings-dialog button.primary {
background-color: #4285f4;
color: white;
}
#explainer-settings-dialog button.secondary {
background-color: #f1f1f1;
color: #333;
}
@media (prefers-color-scheme: dark) {
#explainer-settings-dialog {
background: #333;
color: #eee;
}
#explainer-settings-dialog input[type="text"],
#explainer-settings-dialog select {
background: #444;
color: #eee;
border-color: #555;
}
#explainer-settings-dialog button.secondary {
background-color: #555;
color: #eee;
}
}
`;
document.head.appendChild(styleElement);
// Create dialog content
dialog.innerHTML = `
<h3 style="margin-top:0;">Text Explainer Settings</h3>
<div>
<label for="explainer-language">Language</label>
<select id="explainer-language">
<option value="Chinese" ${this.config.language === 'Chinese' ? 'selected' : ''}>Chinese</option>
<option value="English" ${this.config.language === 'English' ? 'selected' : ''}>English</option>
<option value="Japanese" ${this.config.language === 'Japanese' ? 'selected' : ''}>Japanese</option>
</select>
</div>
<div>
<label for="explainer-provider">Provider</label>
<select id="explainer-provider">
<option value="gemini" ${this.config.provider === 'gemini' ? 'selected' : ''}>Gemini</option>
<option value="openai" ${this.config.provider === 'openai' ? 'selected' : ''}>OpenAI</option>
<option value="anthropic" ${this.config.provider === 'anthropic' ? 'selected' : ''}>Anthropic</option>
</select>
</div>
<div>
<label for="explainer-model">Model</label>
<input id="explainer-model" type="text" value="${this.config.model}">
</div>
<div>
<label for="explainer-api-key">API Key</label>
<input id="explainer-api-key" type="text" value="${this.config.apiKey || ''}">
</div>
<div>
<label for="explainer-base-url">API Base URL</label>
<input id="explainer-base-url" type="text" value="${this.config.baseUrl}">
</div>
<div class="buttons">
<button id="explainer-settings-cancel" class="secondary">Cancel</button>
<button id="explainer-settings-save" class="primary">Save</button>
</div>
`;
document.body.appendChild(dialog);
// Add event listeners
document.getElementById('explainer-settings-save').addEventListener('click', () => {
// Update config with form values
this.update({
language: document.getElementById('explainer-language').value,
model: document.getElementById('explainer-model').value,
apiKey: document.getElementById('explainer-api-key').value,
baseUrl: document.getElementById('explainer-base-url').value,
provider: document.getElementById('explainer-provider').value
});
// Save to storage
this.save();
// Remove dialog
dialog.remove();
styleElement.remove();
// Call save callback if provided
if (typeof onSave === 'function') {
onSave(this.config);
}
});
document.getElementById('explainer-settings-cancel').addEventListener('click', () => {
dialog.remove();
styleElement.remove();
});
// Focus first field
document.getElementById('explainer-language').focus();
}
}
// Make available globally and as a module if needed
window.TextExplainerSettings = TextExplainerSettings;
if (typeof module !== 'undefined') {
module.exports = TextExplainerSettings;
}