Skip to content

Commit 1f2badb

Browse files
authored
Add Popup Options (#28)
* Updates * Adding Popup Options * Update Options * Cleanup
1 parent 0210901 commit 1f2badb

File tree

6 files changed

+126
-123
lines changed

6 files changed

+126
-123
lines changed

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"manifest_version": 3,
3-
"version": "0.3.3",
3+
"version": "0.3.4",
44
"name": "Django Files",
55
"description": "Django Files Web Extension designed to work with github.com/django-files/django-files.",
66
"homepage_url": "https://github.com/django-files/web-extension",

src/html/options.html

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
<link rel="stylesheet" type="text/css" href="../dist/fontawesome/css/all.min.css">
88
<link rel="stylesheet" type="text/css" href="../css/main.css">
99
<link rel="stylesheet" type="text/css" href="../css/options.css">
10-
<script type="text/javascript" src="../js/theme.js"></script>
1110
</head>
1211
<body class="h-100">
1312

@@ -27,6 +26,7 @@ <h1>Django Files Options</h1>
2726
</div>
2827
<div class="clearfix"></div>
2928
<p class="text-center lead">v<span id="version"></span></p>
29+
3030
<table class="table table-sm table-borderless">
3131
<caption class="visually-hidden">Keyboard Shortcuts</caption>
3232
<thead class="visually-hidden"><tr><th>Description</th><th>Shortcut</th></tr></thead>
@@ -35,6 +35,7 @@ <h1>Django Files Options</h1>
3535
<td class="bg-transparent text-end" title="Keyboard Shortcut"><kbd id="mainKey">Unknown</kbd></td>
3636
</tr></tbody>
3737
</table>
38+
3839
<form id="options-form" class="options">
3940
<div class="row">
4041
<div class="col-12 mb-2">
@@ -50,14 +51,15 @@ <h1>Django Files Options</h1>
5051
<div class="col-sm-6 col-12 mb-2">
5152
<label for="recentFiles" class="form-label"><i class="fa-solid fa-list-ol me-2"></i> Recent Files</label>
5253
<input id="recentFiles" aria-describedby="recentFilesHelp" type="number" class="form-control" autocomplete="off">
53-
<div class="form-text" id="recentFilesHelp">Recent Files in Popup, 0 Disabled.</div>
54+
<div class="form-text" id="recentFilesHelp">Popup Recent Files. 0 to Disable.</div>
5455
</div>
5556
<div class="col-sm-6 col-12 mb-2">
56-
<label for="popupTimeout" class="form-label"><i class="fa-solid fa-clock-rotate-left me-2"></i> Preview Timeout</label>
57+
<label for="popupTimeout" class="form-label"><i class="fa-solid fa-stopwatch me-2"></i> Preview Timeout</label>
5758
<input id="popupTimeout" aria-describedby="popupTimeoutHelp" type="number" class="form-control" autocomplete="off">
58-
<div class="form-text" id="popupTimeoutHelp">Timeout Seconds to Hide Preview.</div>
59+
<div class="form-text" id="popupTimeoutHelp">Popup Preview Timeout Seconds.</div>
5960
</div>
6061
</div>
62+
6163
<div class="my-3">
6264
<div class="form-check form-switch mb-2">
6365
<input class="form-check-input" id="contextMenu" type="checkbox" role="switch">
@@ -97,6 +99,7 @@ <h1>Django Files Options</h1>
9799
</div>
98100
</div>
99101
</form>
102+
100103
<hr>
101104
<div class="text-center">
102105
<a class="link-body-emphasis text-decoration-none" target="_blank" rel="noopener"

src/html/popup.html

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616
</div>
1717

1818
<div class="container-fluid p-2">
19-
<div>
20-
<a id="small-auth" class="d-none btn btn-sm btn-outline-secondary disabled float-start add-auth" role="button">
19+
<div class=" mb-1">
20+
<a id="always-auth" class="d-none btn btn-sm btn-outline-secondary disabled float-start me-3 add-auth" role="button">
2121
<i class="fa-solid fa-key"></i></a>
22+
<div class="form-check form-switch float-start form-select-lg" style="padding-top: 1px; padding-bottom: 0;"
23+
data-bs-title="Disable/Enable Mouseover Preview." data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-trigger="hover">
24+
<input class="form-check-input" id="popupPreview" type="checkbox" role="switch">
25+
<label class="form-check-label visually-hidden" for="popupPreview" aria-describedby="popupPreviewHelp"></label>
26+
</div>
2227
<a class="btn btn-sm btn-outline-primary float-end" role="button" href="../html/options.html" title="Options">
2328
<i class="fa-solid fa-gears"></i></a>
24-
<div class="d-flex align-items-center justify-content-center mb-1">
29+
<div class="d-flex align-items-center justify-content-center">
2530
<img src="../media/logo32.png" class="me-2" height="32" width="32" alt="Django Files" title="Django Files">
2631
<h3 class="my-0">Django Files</h3>
2732
</div>
@@ -36,17 +41,10 @@ <h3 class="my-0">Django Files</h3>
3641
<a role="button" class="btn btn-outline-success" href="" data-location="/uppy/">
3742
<i class="fa-solid fa-upload me-2"></i> Upload</a>
3843
</div>
39-
<!-- <a class="btn btn-outline-primary btn-sm" role="button" href="../html/options.html">-->
40-
<!-- <i class="fa-solid fa-sliders me-2"></i> Open Options</a>-->
4144
<a id="auth-button" class="d-none btn btn-lg btn-success w-100 my-2 add-auth" role="button">
4245
<i class="fa-solid fa-key"></i> Add Auth from Current Site</a>
4346
</div>
4447

45-
<!-- <div id="loading-spinner" class="text-center my-3">-->
46-
<!-- <i class="fa-solid fa-sync fa-spin fa-3x"></i>-->
47-
<!-- <p>Loading...</p>-->
48-
<!-- </div>-->
49-
5048
<div id="error-alert" class="d-none alert text-center my-2" role="alert"></div>
5149

5250
<table id="files-table" class="d-none table table-striped table-hover table-sm small align-middle mb-0">

src/js/options.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// JS for options.html
22

33
document.addEventListener('DOMContentLoaded', initOptions)
4-
chrome.runtime.onMessage.addListener(onMessage)
4+
chrome.storage.onChanged.addListener(onChanged)
55
document
66
.querySelectorAll('input')
77
.forEach((el) => el.addEventListener('change', saveOptions))
@@ -13,7 +13,7 @@ document
1313
.forEach((el) => new bootstrap.Tooltip(el))
1414

1515
/**
16-
* Options Init Function
16+
* Initialize Options
1717
* @function initOptions
1818
*/
1919
async function initOptions() {
@@ -36,14 +36,18 @@ async function initOptions() {
3636
}
3737

3838
/**
39-
* On Message Callback
40-
* @function onMessage
41-
* @param {Object} message
39+
* On Changed Callback
40+
* @function onChanged
41+
* @param {Object} changes
42+
* @param {String} namespace
4243
*/
43-
async function onMessage(message) {
44-
// console.log('onMessage: message, sender:', message, sender)
45-
if (message === 'reload-options') {
46-
window.location.reload()
44+
function onChanged(changes, namespace) {
45+
// console.log('onChanged:', changes, namespace)
46+
for (const [key, { newValue }] of Object.entries(changes)) {
47+
if (namespace === 'sync' && key === 'options') {
48+
console.log('newValue:', newValue)
49+
updateOptions(newValue)
50+
}
4751
}
4852
}
4953

src/js/popup.js

Lines changed: 80 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,30 @@ chrome.runtime.onMessage.addListener(onMessage)
55
document
66
.querySelectorAll('a[href]')
77
.forEach((el) => el.addEventListener('click', popupLinks))
8+
document
9+
.querySelectorAll('input')
10+
.forEach((el) => el.addEventListener('change', saveOptions))
811
document
912
.querySelectorAll('.add-auth')
1013
.forEach((el) => el.addEventListener('click', authCredentials))
14+
document
15+
.querySelectorAll('[data-bs-toggle="tooltip"]')
16+
.forEach((el) => new bootstrap.Tooltip(el))
1117

1218
const filesTable = document.getElementById('files-table')
1319
const errorAlert = document.getElementById('error-alert')
1420
const authButton = document.getElementById('auth-button')
1521
const mediaImage = document.getElementById('media-image')
1622
const mediaOuter = document.getElementById('media-outer')
17-
const smallAuth = document.getElementById('small-auth')
23+
const alwaysAuth = document.getElementById('always-auth')
1824

1925
const loadingImage = '../media/loading.gif'
2026
let authError = false
27+
let timeoutID
28+
let timeout
2129

2230
/**
23-
* Popup Init Function
31+
* Initialize Popup
2432
* TODO: Overhaul this function
2533
* @function initPopup
2634
*/
@@ -29,10 +37,13 @@ async function initPopup() {
2937
const { options } = await chrome.storage.sync.get(['options'])
3038
console.log('options:', options)
3139

40+
// Set Options (since this is the only one)
41+
document.getElementById('popupPreview').checked = options.popupPreview
42+
3243
authError = false
3344
// Check auth if checkAuth is enabled in options
3445
if (options.checkAuth) {
35-
smallAuth.classList.remove('d-none')
46+
alwaysAuth.classList.remove('d-none')
3647
}
3748

3849
// If missing auth data or options.checkAuth check current site for auth
@@ -94,7 +105,7 @@ async function initPopup() {
94105

95106
// Check auth if checkAuth is enabled in options
96107
if (options.checkAuth) {
97-
smallAuth.classList.remove('d-none')
108+
alwaysAuth.classList.remove('d-none')
98109
await checkSiteAuth()
99110
}
100111

@@ -111,7 +122,8 @@ async function initPopup() {
111122
// Enable Popup Mouseover Preview if popupPreview
112123
if (options.popupPreview) {
113124
console.log('Enabling Mouseover Preview')
114-
initPopupMouseover(options.popupTimeout)
125+
timeout = options.popupTimeout * 1000
126+
initPopupMouseover()
115127
}
116128
}
117129

@@ -156,8 +168,8 @@ async function onMessage(message) {
156168
await chrome.storage.local.set({ auth })
157169
console.log('New Authentication Found.')
158170
if (options.checkAuth) {
159-
smallAuth.classList.remove('disabled', 'btn-outline-secondary')
160-
smallAuth.classList.add('btn-warning')
171+
alwaysAuth.classList.remove('disabled', 'btn-outline-secondary')
172+
alwaysAuth.classList.add('btn-warning')
161173
}
162174
if (authError) {
163175
authButton.classList.remove('d-none')
@@ -166,6 +178,33 @@ async function onMessage(message) {
166178
}
167179
}
168180

181+
/**
182+
* Save Options Callback
183+
* @function saveOptions
184+
* @param {FormDataEvent} event
185+
*/
186+
async function saveOptions(event) {
187+
// console.log('saveOptions:', event)
188+
const { options } = await chrome.storage.sync.get(['options'])
189+
options[event.target.id] = event.target.checked
190+
console.log(`Set: "${event.target.id}" to target:`, event.target)
191+
console.log('options:', options)
192+
await chrome.storage.sync.set({ options })
193+
if (event.target.id === 'popupPreview') {
194+
if (event.target.checked) {
195+
console.log('popupPreview Enabled. Running initPopupMouseover...')
196+
initPopupMouseover()
197+
} else {
198+
console.log('popupPreview Disabled. Removing Event Listeners...')
199+
document.querySelectorAll('.link-underline').forEach((el) => {
200+
el.removeEventListener('mouseover', onMouseOver)
201+
el.removeEventListener('mouseout', onMouseOut)
202+
})
203+
mediaOuter.classList.add('d-none')
204+
}
205+
}
206+
}
207+
169208
/**
170209
* Add Site Auth Button Callback
171210
* @function authCredentials
@@ -183,11 +222,8 @@ async function authCredentials(event) {
183222
console.log('Auth Credentials Updated...')
184223
authButton.classList.add('d-none')
185224
errorAlert.classList.add('d-none')
186-
smallAuth.classList.add('disabled', 'btn-outline-secondary')
225+
alwaysAuth.classList.add('disabled', 'btn-outline-secondary')
187226
await initPopup()
188-
try {
189-
await chrome.runtime.sendMessage('reload-options')
190-
} catch (e) {} // eslint-disable-line no-empty
191227
} else {
192228
displayAlert({ message: 'Error Getting or Setting Credentials.' })
193229
}
@@ -337,16 +373,8 @@ async function checkSiteAuth() {
337373
} catch (e) {} // eslint-disable-line no-empty
338374
}
339375

340-
/**
341-
* Initialize Popup Mouseover Preview
342-
* @param {Number} timeout
343-
*/
344-
function initPopupMouseover(timeout) {
345-
timeout = timeout * 1000 || 1
346-
console.log('initPopupMouseover: timeout:', timeout)
347-
348-
let timeoutID
349-
376+
function initPopupMouseover() {
377+
console.log('initPopupMouseover')
350378
mediaOuter.addEventListener('mouseover', () => {
351379
mediaOuter.classList.add('d-none')
352380
mediaImage.src = loadingImage
@@ -358,49 +386,43 @@ function initPopupMouseover(timeout) {
358386
console.log('mediaError:', event)
359387
mediaImage.src = '../media/error.png'
360388
})
361-
362389
document.querySelectorAll('.link-underline').forEach((el) => {
363390
el.addEventListener('mouseover', onMouseOver)
364391
el.addEventListener('mouseout', onMouseOut)
365392
})
393+
}
366394

367-
function onMouseOver(event) {
368-
// console.log('onMouseOver:', event)
369-
if (event.pageY < window.innerHeight / 2) {
370-
mediaOuter.classList.remove('top-0')
371-
mediaOuter.classList.add('bottom-0')
372-
} else {
373-
mediaOuter.classList.remove('bottom-0')
374-
mediaOuter.classList.add('top-0')
375-
}
376-
// console.log('name:', event.target.innerText)
377-
// console.log('raw:', event.target.dataset.raw)
378-
const str = event.target.innerText
379-
const imageExtensions = /\.(gif|ico|jpeg|jpg|png|svg|webp)$/i
380-
if (str.match(imageExtensions)) {
381-
mediaImage.src = loadingImage
382-
mediaImage.src = event.target.dataset.raw
383-
mediaOuter.classList.remove('d-none')
384-
} else {
385-
mediaOuter.classList.add('d-none')
386-
mediaImage.src = loadingImage
387-
}
388-
// console.log('timeoutID:', timeoutID)
389-
if (timeoutID) {
390-
clearTimeout(timeoutID)
391-
}
395+
function onMouseOver(event) {
396+
// console.log('onMouseOver:', event)
397+
if (event.pageY < window.innerHeight / 2) {
398+
mediaOuter.classList.remove('top-0')
399+
mediaOuter.classList.add('bottom-0')
400+
} else {
401+
mediaOuter.classList.remove('bottom-0')
402+
mediaOuter.classList.add('top-0')
392403
}
393-
394-
function onMouseOut() {
395-
timeoutID = setTimeout(function () {
396-
mediaOuter.classList.add('d-none')
397-
mediaImage.src = loadingImage
398-
timeoutID = undefined
399-
}, timeout)
404+
// console.log('name:', event.target.innerText)
405+
// console.log('raw:', event.target.dataset.raw)
406+
const str = event.target.innerText
407+
const imageExtensions = /\.(gif|ico|jpeg|jpg|png|svg|webp)$/i
408+
if (str.match(imageExtensions)) {
409+
mediaImage.src = loadingImage
410+
mediaImage.src = event.target.dataset.raw
411+
mediaOuter.classList.remove('d-none')
412+
} else {
413+
mediaOuter.classList.add('d-none')
414+
mediaImage.src = loadingImage
415+
}
416+
// console.log('timeoutID:', timeoutID)
417+
if (timeoutID) {
418+
clearTimeout(timeoutID)
400419
}
401420
}
402421

403-
// function mediaError(event) {
404-
// console.log('mediaError:', event)
405-
// mediaImage.src = '../media/error.png'
406-
// }
422+
function onMouseOut() {
423+
timeoutID = setTimeout(function () {
424+
mediaOuter.classList.add('d-none')
425+
mediaImage.src = loadingImage
426+
timeoutID = undefined
427+
}, timeout)
428+
}

0 commit comments

Comments
 (0)