Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions newtab.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,6 @@
left: 0;
display: none;
}
.toolbar {
position: fixed;
top: 18px;
right: 18px;
z-index: 3;
display: flex;
gap: 8px;
}
.toolbar button,
.fallback button {
border: 1px solid rgba(255,255,255,0.14);
border-radius: 999px;
Expand Down Expand Up @@ -80,12 +71,9 @@
<div class="spinner"></div>
<p>Loading Dashwise...</p>
</div>
<div class="toolbar">
<button id="search-toggle" type="button">Search mode</button>
</div>
<div id="fallback" class="fallback">
<h1>Dashwise is ready</h1>
<p>This Dashwise server cannot be embedded in the new tab page. Use the search mode button to open it with search enabled.</p>
<p id="fallback-message">This Dashwise server cannot be embedded in the new tab page.</p>
</div>
<iframe id="content-frame"></iframe>
<script src="newtab.js"></script>
Expand Down
17 changes: 7 additions & 10 deletions newtab.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
let dashwiseUrl = 'https://www.google.com';
let searchMode = false;

function normalizeUrl(url) {
if (!url) return dashwiseUrl;
Expand Down Expand Up @@ -32,20 +31,18 @@ function loadFrame(url) {
}, 5000);
}

function toggleSearchMode() {
searchMode = !searchMode;
document.getElementById('search-toggle').textContent = searchMode ? 'Exit search mode' : 'Search mode';
loadFrame(setSearchMode(dashwiseUrl, searchMode));
}

function loadDashwise() {
chrome.storage.sync.get({ newTabUrl: 'https://www.google.com' }, (items) => {
chrome.storage.sync.get({ replaceNewTab: true, newTabUrl: 'https://www.google.com', newTabOpenSearch: false }, (items) => {
if (!items.replaceNewTab) {
document.body.classList.add('frame-failed');
document.getElementById('fallback-message').textContent = 'Dashwise new tab replacement is disabled in extension settings.';
return;
}
dashwiseUrl = normalizeUrl(items.newTabUrl);
loadFrame(setSearchMode(dashwiseUrl, searchMode));
loadFrame(setSearchMode(dashwiseUrl, !!items.newTabOpenSearch));
});
}

document.addEventListener('DOMContentLoaded', () => {
document.getElementById('search-toggle').addEventListener('click', toggleSearchMode);
loadDashwise();
});
27 changes: 22 additions & 5 deletions options.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
letter-spacing: 0.5px;
margin-bottom: 4px;
}
input {
input, select {
width: 100%;
padding: 10px 12px;
background: rgba(255,255,255,0.04);
Expand All @@ -33,7 +33,8 @@
font-size: 14px;
outline: none;
}
input:focus { border-color: #6c5ce7; }
input[type="checkbox"] { width: auto; }
input:focus, select:focus { border-color: #6c5ce7; }
.btn {
border: none;
border-radius: 8px;
Expand All @@ -54,10 +55,26 @@
<body>
<h1>Dashwise Settings</h1>
<div class="field">
<label>New Tab URL</label>
<input type="url" id="new-tab-url" placeholder="https://example.com">
<label style="display:flex;align-items:center;gap:8px;text-transform:none;font-size:14px;color:#e8e8ed;">
<input type="checkbox" id="replace-new-tab">
Replace default new tab
</label>
</div>
<button id="save" class="btn btn-primary">Save URL</button>
<div id="new-tab-options">
<div class="field">
<label>Page</label>
<select id="new-tab-page">
<option value="home">Home</option>
</select>
</div>
<div class="field">
<label style="display:flex;align-items:center;gap:8px;text-transform:none;font-size:14px;color:#e8e8ed;">
<input type="checkbox" id="new-tab-open-search">
Open search
</label>
</div>
</div>
<button id="save" class="btn btn-primary">Save Settings</button>
<div id="status"></div>

<hr>
Expand Down
37 changes: 30 additions & 7 deletions options.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,38 @@
(function () {
function buildPageUrl(page, baseUrl) {
const root = (baseUrl || '').replace(/\/+$/, '');
return page && page !== 'home' ? root + '/' + page.replace(/^\/+/, '') : root;
}

function updateNewTabOptionsVisibility() {
document.getElementById('new-tab-options').style.display = document.getElementById('replace-new-tab').checked ? 'block' : 'none';
}

function saveOptions() {
const url = document.getElementById('new-tab-url').value;
chrome.storage.sync.set({ newTabUrl: url }, () => {
const status = document.getElementById('status');
status.textContent = 'Settings saved.';
setTimeout(() => { status.textContent = ''; }, 2000);
const replaceNewTab = document.getElementById('replace-new-tab').checked;
const newTabPage = document.getElementById('new-tab-page').value || 'home';
const newTabOpenSearch = document.getElementById('new-tab-open-search').checked;

chrome.storage.local.get({ dashwiseBaseUrl: '' }, (auth) => {
chrome.storage.sync.set({
replaceNewTab,
newTabPage,
newTabOpenSearch,
newTabUrl: buildPageUrl(newTabPage, auth.dashwiseBaseUrl),
}, () => {
const status = document.getElementById('status');
status.textContent = 'Settings saved.';
setTimeout(() => { status.textContent = ''; }, 2000);
});
});
}

function restoreOptions() {
chrome.storage.sync.get({ newTabUrl: 'https://www.google.com' }, (items) => {
document.getElementById('new-tab-url').value = items.newTabUrl;
chrome.storage.sync.get({ replaceNewTab: true, newTabPage: 'home', newTabOpenSearch: false }, (items) => {
document.getElementById('replace-new-tab').checked = !!items.replaceNewTab;
document.getElementById('new-tab-page').value = items.newTabPage || 'home';
document.getElementById('new-tab-open-search').checked = !!items.newTabOpenSearch;
updateNewTabOptionsVisibility();
});
}

Expand All @@ -24,6 +46,7 @@

document.addEventListener('DOMContentLoaded', () => {
restoreOptions();
document.getElementById('replace-new-tab').addEventListener('change', updateNewTabOptionsVisibility);
document.getElementById('save').addEventListener('click', saveOptions);
document.getElementById('logout-btn').addEventListener('click', handleLogout);
});
Expand Down
25 changes: 19 additions & 6 deletions popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
Add to Links
</div>
<div class="action-item" id="action-read-later">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></svg>
Save to Read Later
</div>
<div class="action-item" id="action-qr">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>
Generate QR Code
</div>
</div>
<div id="qr-preview" style="display:none;margin-top:12px;text-align:center;"></div>
</div>

<div class="section">
Expand All @@ -340,8 +337,24 @@
<h2>Settings</h2>
</div>
<div class="settings-row">
<label>New Tab URL</label>
<input type="url" id="new-tab-url" placeholder="https://example.com">
<label style="display:flex;align-items:center;gap:8px;text-transform:none;font-size:14px;color:var(--text);">
<input type="checkbox" id="replace-new-tab" style="width:auto;">
Replace default new tab
</label>
</div>
<div id="new-tab-options">
<div class="settings-row">
<label>Page</label>
<select id="new-tab-page" style="background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);padding:10px 12px;color:var(--text);font-size:14px;outline:none;appearance:auto;width:100%;">
<option value="home">Home</option>
</select>
</div>
<div class="settings-row">
<label style="display:flex;align-items:center;gap:8px;text-transform:none;font-size:14px;color:var(--text);">
<input type="checkbox" id="new-tab-open-search" style="width:auto;">
Open search
</label>
</div>
</div>
<div id="settings-status" class="success" style="min-height:0;"></div>
<div class="settings-actions">
Expand Down
64 changes: 28 additions & 36 deletions popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,31 +179,6 @@
}
}

async function saveReadLater() {
const tab = await getActiveTab();
if (!tab || !tab.url) { showToast('No active tab'); return; }

const item = {
title: tab.title || tab.url,
url: tab.url,
savedAt: new Date().toISOString(),
};

try {
await apiFetch('/links/items', {
method: 'POST',
body: JSON.stringify({ title: item.title, url: item.url, tags: ['read-later'] }),
});
showToast('Saved to read later');
} catch (err) {
const existing = await storageGet({ dashwiseReadLater: [] });
const items = existing.dashwiseReadLater.filter((saved) => saved.url !== item.url);
items.unshift(item);
await storageSet({ dashwiseReadLater: items.slice(0, 250) });
showToast('Saved locally for read later');
}
}

// ---- Add Link Screen ----
let addLinkTab = null;

Expand Down Expand Up @@ -317,7 +292,7 @@

const payload = { title: name, url: url };
if (icon) payload.iconUrl = icon;
if (collection) payload.linkGroup = collection;
if (collection) payload.collection = collection;
if (tagsRaw) payload.tags = tagsRaw.split(',').map((t) => t.trim()).filter(Boolean);

console.log('[Dashwise] submit payload:', JSON.stringify(payload));
Expand Down Expand Up @@ -356,19 +331,36 @@
function generateQR() {
getActiveTab().then((tab) => {
const url = tab ? encodeURIComponent(tab.url) : '';
chrome.tabs.create({ url: 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' + url });
const preview = document.getElementById('qr-preview');
if (!url) { showToast('No active tab'); return; }
preview.style.display = 'block';
preview.innerHTML = '<img src="https://api.qrserver.com/v1/create-qr-code/?size=180x180&data=' + url + '" alt="QR code" style="width:180px;height:180px;border-radius:8px;background:#fff;padding:8px;">';
});
}

// ---- Settings ----
async function loadNewTabUrl() {
const items = await syncGet({ newTabUrl: 'https://www.google.com' });
document.getElementById('new-tab-url').value = items.newTabUrl;
function buildPageUrl(page) {
const root = baseUrl.replace(/\/+$/, '');
return page && page !== 'home' ? root + '/' + page.replace(/^\/+/, '') : root;
}

function updateNewTabOptionsVisibility() {
document.getElementById('new-tab-options').style.display = document.getElementById('replace-new-tab').checked ? 'block' : 'none';
}

async function loadNewTabSettings() {
const items = await syncGet({ replaceNewTab: true, newTabPage: 'home', newTabOpenSearch: false });
document.getElementById('replace-new-tab').checked = !!items.replaceNewTab;
document.getElementById('new-tab-page').value = items.newTabPage || 'home';
document.getElementById('new-tab-open-search').checked = !!items.newTabOpenSearch;
updateNewTabOptionsVisibility();
}

async function saveNewTabUrl() {
const url = document.getElementById('new-tab-url').value.trim();
await syncSet({ newTabUrl: url || 'https://www.google.com' });
async function saveNewTabSettings() {
const replaceNewTab = document.getElementById('replace-new-tab').checked;
const newTabPage = document.getElementById('new-tab-page').value || 'home';
const newTabOpenSearch = document.getElementById('new-tab-open-search').checked;
await syncSet({ replaceNewTab, newTabPage, newTabOpenSearch, newTabUrl: buildPageUrl(newTabPage) });
const status = document.getElementById('settings-status');
status.textContent = 'Saved';
status.style.color = '#2ecc71';
Expand All @@ -395,18 +387,18 @@
document.getElementById('login-btn').addEventListener('click', handleLogin);

document.getElementById('settings-btn').addEventListener('click', () => {
loadNewTabUrl();
loadNewTabSettings();
showScreen('settings');
});
document.getElementById('settings-back').addEventListener('click', () => {
showScreen('main');
});
document.getElementById('save-url-btn').addEventListener('click', saveNewTabUrl);
document.getElementById('replace-new-tab').addEventListener('change', updateNewTabOptionsVisibility);
document.getElementById('save-url-btn').addEventListener('click', saveNewTabSettings);
document.getElementById('logout-btn').addEventListener('click', handleLogout);

document.getElementById('action-home-link').addEventListener('click', addToHomeLinks);
document.getElementById('action-add-link').addEventListener('click', openAddLink);
document.getElementById('action-read-later').addEventListener('click', saveReadLater);
document.getElementById('action-qr').addEventListener('click', generateQR);

document.getElementById('add-link-back').addEventListener('click', closeAddLink);
Expand Down