Skip to content

Commit 8597cac

Browse files
authored
Context Menu (#35)
* Update Toast Container * Add Context Menu * Update Context Menu * Update Error Handling * Tweak Context Menu * Re-Work CTX Menu for New Files Endpoint * Fixes and Backwards Compatibility * Bump Version * Add Expire to CTX * Add Password and Private * Tweaks * Fix * Cleanup
1 parent 325f52e commit 8597cac

File tree

8 files changed

+465
-170
lines changed

8 files changed

+465
-170
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.6",
3+
"version": "0.4.0",
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/css/main.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ svg {
55
width: 1em;
66
margin-bottom: 0.15em;
77
}
8+
9+
#toast-container {
10+
z-index: 4;
11+
}

src/css/options.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ video {
2121
}
2222

2323
.card {
24-
min-width: 380px;
24+
min-width: 400px;
2525
}
2626

2727
.card,

src/css/popup.css

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* CSS for popup.html */
22

33
body {
4-
width: 380px;
4+
width: 400px;
55
overflow-x: hidden;
66
}
77

@@ -14,6 +14,7 @@ body {
1414
background-color: #303030;
1515
}
1616

17-
#toast-container {
18-
z-index: 4;
17+
ul.dropdown-menu {
18+
max-width: 320px;
19+
min-width: 180px;
1920
}

src/html/popup.html

Lines changed: 86 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424

2525
<div class="container-fluid p-2">
2626
<div class=" mb-1">
27-
<div class="form-check form-switch float-start form-select-lg me-2" style="padding-top: 1px; padding-bottom: 0;"
27+
<div class="form-check form-switch float-start form-select-lg me-2 pb-0" style="padding-top: 1px;"
2828
data-bs-title="Disable/Enable Mouseover Preview." data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-trigger="hover">
2929
<input class="form-check-input" id="popupPreview" type="checkbox" role="switch">
30-
<label class="form-check-label visually-hidden" for="popupPreview" aria-describedby="popupPreviewHelp"></label>
30+
<label class="form-check-label visually-hidden" for="popupPreview" aria-describedby="popupPreviewHelp">Popup Preview</label>
3131
</div>
3232
<a id="always-auth" class="d-none btn btn-sm btn-outline-warning float-start add-auth" role="button"
3333
data-bs-title="Update Authentication with Current Site." data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-trigger="hover">
@@ -57,42 +57,113 @@ <h3 class="my-0">Django Files</h3>
5757

5858
<table id="files-table" class="d-none table table-striped table-hover table-sm small align-middle mb-0">
5959
<caption class="visually-hidden">Recent Uploads</caption>
60-
<thead class="visually-hidden"><tr><th>Copy</th><th>File URL</th><th>Delete</th></tr></thead>
60+
<thead class="visually-hidden"><tr><th>Menu</th><th>File URL</th></tr></thead>
6161
<tbody></tbody>
6262
<tfoot class="d-none">
6363
<tr>
6464
<td colspan="align-middle" style="width: 20px;"><i class="fa-solid fa-spinner fa-spin"></i></td>
6565
<td class="placeholder-glow"><span class="placeholder" style="width: 100%;"></span></td>
66-
<td class="placeholder-glow" style="width: 20px;"><i class="fa-solid fa-circle-dot fa-xs"></i></td>
6766
</tr>
6867
</tfoot>
6968
</table>
7069
</div>
7170

7271
<div aria-live="polite" aria-atomic="true" class="">
73-
<div id="toast-container" class="toast-container bottom-0 end-0 p-3"></div>
72+
<div id="toast-container" class="toast-container d-flex flex-column-reverse top-0 start-0 p-3"></div>
7473
</div>
7574

7675
<div class="d-none">
77-
<div class="toast align-items-center border-0 mt-3" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="5000">
78-
<div class="d-flex">
79-
<div class="toast-body small"></div>
80-
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
81-
</div>
76+
<div class="toast align-items-center border-0 mb-3" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="5000">
77+
<div class="toast-body text-break small"></div>
8278
</div>
83-
</div>
79+
80+
<input id="ctx-menu-row" type="hidden" value="">
81+
82+
<ul class="dropdown-menu py-1">
83+
<li class="small"><a class="dropdown-item clip copy-link">
84+
<i class="fa-solid fa-copy link-body-emphasis me-3"></i> Copy Share Link</a></li>
85+
<li class="small"><a class="dropdown-item clip copy-raw">
86+
<i class="fa-regular fa-copy link-body-emphasis me-3"></i> Copy Raw Link</a></li>
87+
<li><hr class="dropdown-divider my-1"></li>
88+
<li class="small"><a class="dropdown-item clip raw" href="">
89+
<i class="fa-solid fa-arrow-up-right-from-square link-body-emphasis me-3"></i> Open Raw File</a></li>
90+
<li class="small"><a class="dropdown-item" data-action="delete">
91+
<i class="fa-regular fa-trash-can link-danger me-3"></i> Delete File</a></li>
92+
<li><hr class="dropdown-divider my-1"></li>
93+
<li class="dropdown-item-text text-center text-break small clip mouse-link py-0"></li>
94+
<li class="dropdown-item-text text-center file-icons">
95+
<span class="text-body-tertiary view-text">0</span>
96+
<i class="fa-solid fa-eye text-body-tertiary mx-1"></i>
97+
<a data-action="private"><i class="fa-solid fa-lock mx-1 text-body-tertiary"></i></a>
98+
<a class="pass-link" data-action="password"><i class="fa-solid fa-key mx-1 text-body-tertiary"></i></a>
99+
<a class="text-decoration-none link-body-emphasis" data-action="expire">
100+
<i class="fa-solid fa-hourglass-start mx-1 text-body-tertiary"></i>
101+
<span class="expr-text"></span></a>
102+
</li>
103+
</ul>
104+
</div> <!-- d-none -->
84105

85106
<div class="modal fade" id="delete-modal" tabindex="-1" aria-hidden="true">
86107
<div class="modal-dialog modal-dialog-centered">
87108
<div class="modal-content">
88109
<div class="modal-body text-center">
89110
<p>Are you sure you want to delete this file?</p>
90-
<p><kbd id="delete-name" class="text-break"></kbd></p>
111+
<p class="text-break"><kbd class="file-name"></kbd></p>
112+
</div>
113+
<div class="modal-footer">
114+
<button type="button" class="btn btn-danger me-auto" id="confirm-delete">
115+
<i class="fa-regular fa-trash-can me-2"></i> Delete</button>
116+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
117+
Close <i class="fa-solid fa-xmark ms-2"></i></button>
118+
</div>
119+
</div> <!-- modal-content -->
120+
</div> <!-- modal-dialog -->
121+
</div> <!-- modal -->
122+
123+
<div class="modal fade" id="expire-modal" tabindex="-1" aria-hidden="true">
124+
<div class="modal-dialog modal-dialog-centered">
125+
<div class="modal-content">
126+
<div class="modal-body">
127+
<p class="text-center">
128+
Set the file's expiration. <br>
129+
For examples, see
130+
<a href="https://github.com/onegreyonewhite/pytimeparse2#pytimeparse2-time-expression-parser" target="_blank" rel="noopener">
131+
this README.md</a>.
132+
</p>
133+
<p class="text-center text-break"><kbd class="file-name"></kbd></p>
134+
<form id="expire-form">
135+
<label for="expire-input" class="form-label"><i class="fa-solid fa-hourglass-start me-1"></i> Expiration</label>
136+
<input id="expire-input" aria-describedby="expire-input-help" class="form-control" type="text" autocomplete="off">
137+
<div class="form-text" id="expire-input-help" >File Expiration (Blank to Disable Expiration).</div>
138+
</form>
139+
</div>
140+
<div class="modal-footer">
141+
<button type="submit" form="expire-form" class="btn btn-success me-auto">
142+
<i class="fa-regular fa-floppy-disk me-2"></i> Save</button>
143+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
144+
Close <i class="fa-solid fa-xmark ms-2"></i></button>
145+
</div>
146+
</div> <!-- modal-content -->
147+
</div> <!-- modal-dialog -->
148+
</div> <!-- modal -->
149+
150+
<div class="modal fade" id="password-modal" tabindex="-1" aria-hidden="true">
151+
<div class="modal-dialog modal-dialog-centered">
152+
<div class="modal-content">
153+
<div class="modal-body">
154+
<p class="text-center">Set the file's Password.</p>
155+
<p class="text-center text-break"><kbd class="file-name"></kbd></p>
156+
<form id="password-form">
157+
<label for="password-input" class="form-label"><i class="fa-solid fa-key me-1"></i> Password</label>
158+
<input id="password-input" aria-describedby="password-input-help" class="form-control" type="text" autocomplete="off">
159+
<div class="form-text" id="password-input-help" >File Password (Blank to Disable Password).</div>
160+
</form>
91161
</div>
92162
<div class="modal-footer">
93-
<button type="button" class="btn btn-danger" id="confirm-delete">
94-
Delete <i class="fa-regular fa-trash-can ms-1"></i></button>
95-
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
163+
<button type="submit" form="password-form" class="btn btn-success me-auto">
164+
<i class="fa-regular fa-floppy-disk me-2"></i> Save</button>
165+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
166+
Close <i class="fa-solid fa-xmark ms-2"></i></button>
96167
</div>
97168
</div> <!-- modal-content -->
98169
</div> <!-- modal-dialog -->

src/js/options.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ document
1717
* @function initOptions
1818
*/
1919
async function initOptions() {
20-
// console.log('initOptions')
20+
// console.debug('initOptions')
2121
document.getElementById('version').textContent =
2222
chrome.runtime.getManifest().version
2323

2424
const { options } = await chrome.storage.sync.get(['options'])
25-
console.log('options:', options)
25+
console.debug('options:', options)
2626
updateOptions(options)
2727
if (!options?.siteUrl) {
2828
const siteUrl = document.getElementById('siteUrl')
@@ -42,10 +42,10 @@ async function initOptions() {
4242
* @param {String} namespace
4343
*/
4444
function onChanged(changes, namespace) {
45-
// console.log('onChanged:', changes, namespace)
45+
// console.debug('onChanged:', changes, namespace)
4646
for (const [key, { newValue }] of Object.entries(changes)) {
4747
if (namespace === 'sync' && key === 'options') {
48-
console.log('newValue:', newValue)
48+
console.debug('newValue:', newValue)
4949
updateOptions(newValue)
5050
}
5151
}
@@ -57,7 +57,7 @@ function onChanged(changes, namespace) {
5757
* @param {FormDataEvent} event
5858
*/
5959
async function saveOptions(event) {
60-
// console.log('saveOptions:', event)
60+
// console.debug('saveOptions:', event)
6161
const { options } = await chrome.storage.sync.get(['options'])
6262
if (event.target.type === 'checkbox') {
6363
options[event.target.id] = event.target.checked
@@ -75,8 +75,8 @@ async function saveOptions(event) {
7575
} else {
7676
options[event.target.id] = event.target.value
7777
}
78-
console.log(`Set: "${event.target.id}" to target:`, event.target)
79-
console.log('options:', options)
78+
console.info(`Set: "${event.target.id}" to target:`, event.target)
79+
console.debug('options:', options)
8080
await chrome.storage.sync.set({ options })
8181
}
8282

@@ -87,7 +87,7 @@ async function saveOptions(event) {
8787
*/
8888
function updateOptions(options) {
8989
for (const [key, value] of Object.entries(options)) {
90-
// console.log(`${key}: ${value}`)
90+
// console.debug(`${key}: ${value}`)
9191
const element = document.getElementById(key)
9292
if (element) {
9393
if (typeof value === 'boolean') {

0 commit comments

Comments
 (0)