aboutsummaryrefslogtreecommitdiff
path: root/static/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'static/widgets')
-rw-r--r--static/widgets/editable/index.css36
-rw-r--r--static/widgets/editable/index.js77
-rw-r--r--static/widgets/image/index.css134
-rw-r--r--static/widgets/image/index.js108
-rw-r--r--static/widgets/index.js6
-rw-r--r--static/widgets/month-select/index.css134
-rw-r--r--static/widgets/month-select/index.js87
-rw-r--r--static/widgets/password-dialog/index.css51
-rw-r--r--static/widgets/password-dialog/index.js60
-rw-r--r--static/widgets/search/index.css50
-rw-r--r--static/widgets/search/index.js68
-rw-r--r--static/widgets/upload-bar/index.css41
-rw-r--r--static/widgets/upload-bar/index.js44
13 files changed, 0 insertions, 896 deletions
diff --git a/static/widgets/editable/index.css b/static/widgets/editable/index.css
deleted file mode 100644
index b474370..0000000
--- a/static/widgets/editable/index.css
+++ /dev/null
@@ -1,36 +0,0 @@
-
-#container {
- width: 100%;
- background: var(--card-background);
- box-shadow: var(--shadow);
- border-radius: var(--border-radius);
- display: grid;
- grid-template-columns: min-content auto min-content;
-}
-
-#container label {
- user-select: none;
- font-weight: bold;
- background: var(--primary);
- color: var(--fg-primary);
- align-content: center;
- padding: 10px;
- border-top-left-radius: var(--border-radius);
- border-bottom-left-radius: var(--border-radius);
-}
-
-#container input {
- background: var(--card-background);
- user-select: none;
- font-size: 1em;
-}
-
-#container input:read-only {
- caret-color: transparent;
-}
-
-#edit {
- width: 35px;
- padding: 10px;
- cursor: pointer;
-}
diff --git a/static/widgets/editable/index.js b/static/widgets/editable/index.js
deleted file mode 100644
index b7e24de..0000000
--- a/static/widgets/editable/index.js
+++ /dev/null
@@ -1,77 +0,0 @@
-import icons from 'icons';
-import * as sfw from 'sfw';
-const { Div, Label, Input } = sfw.element.native;
-
-import stylesheet from './index.css';
-
-const css = await sfw.css.sheet(stylesheet);
-
-export default class Editable extends sfw.element.Container {
- #label
- #input
- #edit
-
- constructor() {
- super({ css });
-
- this.onupdate = () => {};
-
- this.body.append(
- Div.new({
- id: 'container',
- children: [
- this.#label = Label.new({ htmlFor: 'input' }),
- this.#input = Input.new({
- readOnly: true,
- onkeydown: (e) => {
- if (e.key === 'Enter') {
- this.#input.readOnly = true;
- this.#update()
- this.onupdate();
- }
- },
- }),
- this.#edit = Div.new({
- id: 'edit',
- children: [ icons.edit ],
- onclick: () => {
- this.#input.readOnly = !this.#input.readOnly;
- this.#update();
-
- if (this.#input.readOnly) {
- this.onupdate();
- }
- }
- }),
- ],
- })
- );
- }
-
- #update() {
- this.#edit.innerHTML = '';
- this.#edit.append(
- this.#input.readOnly ? icons.edit : icons.check
- );
-
- if (!this.#input.readOnly) {
- this.#input.select();
- }
- }
-
- set title(value) {
- this.#label.innerText = value;
- }
-
- set value(value) {
- this.#input.value = value;
- }
-
- get value() {
- return this.#input.value;
- }
-
- set type(type) {
- this.#input.type = type;
- }
-}
diff --git a/static/widgets/image/index.css b/static/widgets/image/index.css
deleted file mode 100644
index a4105e9..0000000
--- a/static/widgets/image/index.css
+++ /dev/null
@@ -1,134 +0,0 @@
-#container {
- position: relative;
- height: 100%;
- min-height: 100px;
- border-radius: var(--border-radius);
- overflow: hidden;
- box-shadow: #223223aa 1px 1px 4px;
- background: var(--card-background);
- margin: auto;
-}
-
-#container img {
- border-radius: var(--border-radius);
- max-width: 700px;
- width: calc(100vw - 20px);
- visibility: hidden;
- margin-bottom: -5px;
- height: calc((100vw - 20px) * 0.8);
-}
-
-#container.loaded img {
- visibility: visible;
- width: 100%;
- height: unset;
-}
-
-@keyframes loader {
- 0% {
- width: 60px;
- height: 60px;
- }
-
- 25% {
- border: 5px solid var(--page-background);
- }
-
- 50% {
- width: 80px;
- height: 80px;
- }
-
- 75% {
- border: 10px solid var(--page-background);
- }
-
- 100% {
- width: 60px;
- height: 60px;
- }
-}
-
-#loading {
- position: absolute;
- border: 10px solid var(--page-background);
- border-radius: 100%;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- animation: 0.5s infinite loader ease;
-}
-
-.loaded #loading {
- display: none;
-}
-
-#menu {
- position: absolute;
- top: 0px;
- left: 0px;
- height: 100%;
- width: 0px;
- background: #efefef99;
- backdrop-filter: blur(5px);
- border-radius: var(--border-radius);
- transition: width 0.2s ease, padding 0.2s ease;
- overflow: hidden;
- align-content: center;
- overflow: hidden;
- padding: 0px;
- display: grid;
- grid-template-columns: 1fr;
- gap: 10px;
-}
-
-#menu.open {
- width: 100%;
- padding: 10px;
-}
-
-#delete {
- background: #ee5151;
- padding: 10px;
- color: #fff;
- font-weight: bold;
- border-radius: var(--border-radius);
- cursor: pointer;
- user-select: none;
-}
-
-#download {
- background: var(--primary);
- padding: 10px;
- border-radius: var(--border-radius);
- color: #fff;
- font-weight: bold;
- user-select: none;
- cursor: pointer;
-}
-
-#label {
- display: grid;
- grid-template-columns: 55px auto;
-}
-
-#label #title {
- padding: 10px;
- background: var(--primary);
- border-top-left-radius: var(--border-radius);
- border-bottom-left-radius: var(--border-radius);
- color: #fff;
- font-weight: bold;
- user-select: none;
-}
-
-.element {
- background: #efefef99;
- padding: 10px;
- font-weight: bold;
- overflow-x: auto;
- user-select: none;
- white-space: nowrap;
- border-top-right-radius: var(--border-radius);
- border-bottom-right-radius: var(--border-radius);
-}
diff --git a/static/widgets/image/index.js b/static/widgets/image/index.js
deleted file mode 100644
index b063864..0000000
--- a/static/widgets/image/index.js
+++ /dev/null
@@ -1,108 +0,0 @@
-import * as api from 'api';
-import * as sfw from 'sfw';
-import Month from '../../month.js';
-const { Div, Img, A: Link } = sfw.element.native;
-
-import stylesheet from './index.css';
-
-const css = await sfw.css.sheet(stylesheet);
-
-export default class Image extends sfw.element.Container {
- #container
- #image
- #menu
- #id
- #month
- #date
- #id_element
- #disabled
-
- constructor() {
- super ({ css })
-
- this.#disabled = false;
-
- this.body.append(
- this.#container = Div.new({
- id: 'container',
- children: [
- this.#image = Img.new({
- onload: () => this.#container.classList.add('loaded'),
- }),
- Div.new({ id: 'loading' }),
- this.#menu = Div.new({
- id: 'menu',
- children: [
- Div.new({
- id: 'label',
- children: [
- Div.new({ id: 'title', innerText: 'Id' }),
- this.#id_element = Div.new({ className: 'element id' }),
- ],
- }),
- Div.new({
- id: 'label',
- children: [
- Div.new({ id: 'title', innerText: 'Date' }),
- this.#date = Div.new({ className: 'element' }),
- ],
- }),
- Div.new({
- id: 'download',
- innerText: 'Download',
- onclick: () => {
- const a = Link.new({
- href: `/api/image/load/${this.#id}`,
- download: `${this.#id}.jpeg`
- })
- a.click()
- }
- }),
- Div.new({
- id: 'delete',
- innerText: 'Delete',
- onclick: () => {
- api.images.remove(this.#id);
- this.parentNode.removeChild(this);
- }
- }),
- ],
- ondblclick: (e) => {
- if (e.target != this.#menu) {
- e.stopPropagation();
- }
- }
- })
- ],
- ondblclick: (e) => {
- if (!this.#disabled) {
- this.#menu.classList.toggle('open');
- e.preventDefault();
- }
- }
- })
- );
- }
-
- set metadata(image) {
- const date = new Date(image.timestamp * 1000);
- this.#id = image.id;
- this.#month = Month.from_unix(image.timestamp);
- this.#container.classList.remove('loaded');
- this.#date.innerText = date.toLocaleString();
- this.#id_element.innerText = image.id;
- }
-
- load() {
- this.#image.src = `/api/image/load/${this.#id}`;
- }
-
- get month() {
- return this.#month;
- }
-
- set disabled(value) {
- this.#disabled = value;
- this.#image.setAttribute('draggable', !value);
- }
-}
diff --git a/static/widgets/index.js b/static/widgets/index.js
deleted file mode 100644
index 6220318..0000000
--- a/static/widgets/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export { default as Editable } from './editable/index.js';
-export { default as Image } from './image/index.js';
-export { default as MonthSelect } from './month-select/index.js';
-export { default as PasswordDialog } from './password-dialog/index.js';
-export { default as Search } from './search/index.js';
-export { default as UploadBar } from './upload-bar/index.js';
diff --git a/static/widgets/month-select/index.css b/static/widgets/month-select/index.css
deleted file mode 100644
index 25ed5d2..0000000
--- a/static/widgets/month-select/index.css
+++ /dev/null
@@ -1,134 +0,0 @@
-:host {
- position: fixed;
- top: 0;
- left: 0;
-}
-
-#container {
- z-index: 1000;
- position: fixed;
- bottom: -100%;
- left: 5px;
- right: 5px;
- background: #fff9;
- backdrop-filter: blur(10px);
- border-radius: var(--border-radius);
- transition: bottom 0.2s ease;
- height: calc(100% - 10px);
- box-shadow: var(--shadow);
- padding: 10px;
-}
-
-#container.visible {
- bottom: 5px;
-}
-
-#close-button {
- position: absolute;
- top: 10px;
- right: 10px;
- width: 25px;
- height: 25px;
- border-radius: 100%;
- background: var(--page-background);
- cursor: pointer;
-}
-
-#title {
- font-size: 1.2em;
- user-select: none;
- margin-bottom: 10px;
-}
-
-#month-container {
- height: calc(100% - 30px);
- overflow-y: auto;
- overscroll-behavior: contain;
-}
-
-.month-item {
- padding: 10px;
- padding-left: 20px;
- margin: 5px;
- border-radius: var(--border-radius);
- user-select: none;
- cursor: pointer;
- position: relative;
-}
-
-.month-item.none {
- font-style: italic;
-}
-
-.month-item:before {
- content: '';
- display: block;
- position: absolute;
- background: var(--primary);
- top: 0px;
- left: 0px;
- width: 4px;
- height: 47px;
-}
-
-.month-item:after {
- content: '';
- display: block;
- position: absolute;
- background: var(--primary);
- top: 50%;
- transform: translate(0, -50%);
- left: 0px;
- width: 12px;
- height: 4px;
-}
-
-.month-item:first-child:before {
- top: 50%;
- height: 27px;
-}
-
-.month-item.none:before {
- top: 0;
- height: 20px;
-}
-
-.month-item:hover {
- background: var(--primary);
- color: var(--fg-primary);
-}
-
-.year-item {
- padding: 10px 20px;
- font-size: 1.1em;
- margin: 5px;
- position: relative;
- font-weight: bold;
- background: #fffa;
- border-radius: var(--border-radius);
- box-shadow: #22322355 1px 1px 2px;
-}
-
-.year-item:before {
- content: '';
- display: block;
- position: absolute;
- background: var(--primary);
- top: 0px;
- left: 0px;
- width: 4px;
- height: 50px;
-}
-
-.year-item:after {
- content: '';
- display: block;
- position: absolute;
- background: var(--primary);
- top: 50%;
- transform: translate(0, -50%);
- left: -4px;
- width: 12px;
- height: 12px;
- border-radius: 100%;
-}
diff --git a/static/widgets/month-select/index.js b/static/widgets/month-select/index.js
deleted file mode 100644
index 7e4d583..0000000
--- a/static/widgets/month-select/index.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import icons from 'icons';
-import * as sfw from 'sfw';
-const { Div } = sfw.element.native;
-
-import stylesheet from './index.css';
-
-const css = await sfw.css.sheet(stylesheet);
-
-export default class MonthSelect extends sfw.element.Container {
- #container
- #month_container
-
- constructor() {
- super({ css });
-
- this.onscroll = (e) => e.stopPropagate();
- this.onmonth = () => {};
-
- this.body.append(
- this.#container = Div.new({
- id: 'container',
- children: [
- Div.new({ id: 'title', innerText: 'Select Month' }),
- Div.new({
- id: 'close-button',
- children: [ icons.close ],
- onclick: () => this.hide(),
- }),
- this.#month_container = Div.new({
- id: 'month-container',
- }),
- ],
- }),
- );
- }
-
- show() {
- this.#container.classList.add('visible');
- }
-
- hide() {
- this.#container.classList.remove('visible');
- }
-
- set months(months) {
- months.sort((a, b) => a.is_before(b));
-
- this.#month_container.innerHTML = '';
-
- let last = null;
-
- for (const month of months) {
- if (last != null && !last.is_same_year(month)) {
- this.#month_container.append(
- Div.new({
- className: 'year-item',
- innerText: last.year,
- })
- );
- }
-
- this.#month_container.append(
- Div.new({
- className: 'month-item',
- innerText: month.name,
- onclick: () => {
- this.hide();
- this.onmonth(month);
- }
- })
- );
-
- last = month;
- }
-
- this.#month_container.append(
- Div.new({
- className: 'month-item none',
- innerText: 'No Date',
- onclick: () => {
- this.hide();
- this.onmonth(null);
- }
- })
- );
- }
-}
diff --git a/static/widgets/password-dialog/index.css b/static/widgets/password-dialog/index.css
deleted file mode 100644
index ad8c1c2..0000000
--- a/static/widgets/password-dialog/index.css
+++ /dev/null
@@ -1,51 +0,0 @@
-#container {
- position: absolute;
- max-width: 500px;
- width: 70%;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- display: grid;
- gap: 10px;
- background: #efefef99;
- backdrop-filter: blur(10px);
- padding: 10px;
- border-radius: var(--border-radius);
- box-shadow: var(--shadow);
-}
-
-#title {
- font-size: 1.1em;
-}
-
-#close {
- width: 25px;
- height: 25px;
- position: absolute;
- top: 5px;
- right: 5px;
- cursor: pointer;
- background: var(--page-background);
- border-radius: 100%;
- padding: 2px;
-}
-
-#button {
- background: var(--primary);
- padding: 10px;
- color: var(--fg-primary);
- font-weight: bold;
- border-radius: var(--border-radius);
- box-shadow: var(--box-shadow);
- text-align: center;
-}
-
-#error {
- font-style: italic;
- font-weight: bold;
- color: #ee5151;
-}
-
-#error.hidden {
- display: none;
-}
diff --git a/static/widgets/password-dialog/index.js b/static/widgets/password-dialog/index.js
deleted file mode 100644
index 76fbec6..0000000
--- a/static/widgets/password-dialog/index.js
+++ /dev/null
@@ -1,60 +0,0 @@
-import * as api from 'api';
-import icons from 'icons';
-import * as sfw from 'sfw';
-const { Div, Input } = sfw.element.native;
-
-import stylesheet from './index.css';
-
-const css = await sfw.css.sheet(stylesheet);
-
-export default class PasswordDialog extends sfw.element.Container {
- #current
- #new
- #confirm
- #error
-
- constructor() {
- super({ css });
-
- this.callclose = () => this.close();
-
- document.body.addEventListener('click', this.callclose);
- this.onclick = (e) => e.stopPropagation();
-
- this.body.append(Div.new({
- id: 'container',
- children: [
- Div.new({ id: 'title', innerText: 'Change Password' }),
- Div.new({ id: 'close', children: [ icons.close ], onclick: () => this.close() }),
- this.#current = Input.new({ placeholder: 'Current Password', type: 'password' }),
- this.#new = Input.new({ placeholder: 'New Password', type: 'password' }),
- this.#confirm = Input.new({ placeholder: 'Confirm Password', type: 'password' }),
- this.#error = Div.new({ id: 'error', className: 'hidden' }),
- Div.new({
- id: 'button',
- innerText: 'Update',
- onclick: async () => {
- if (this.#new.value !== this.#confirm.value) {
- this.#error.innerText = 'Passwords do not match';
- this.#error.className = '';
- return;
- }
-
- if (!await api.profile.update_password(this.#current.value, this.#new.value)) {
- this.#error.innerText = 'invalid password';
- this.#error.className = '';
- return;
- }
-
- this.close();
- },
- }),
- ],
- }));
- }
-
- close() {
- this.parentNode.removeChild(this);
- document.body.removeEventListener('click', this.callclose);
- }
-}
diff --git a/static/widgets/search/index.css b/static/widgets/search/index.css
deleted file mode 100644
index 14e650d..0000000
--- a/static/widgets/search/index.css
+++ /dev/null
@@ -1,50 +0,0 @@
-:host {
- position: fixed;
- top: 0;
- left: 0;
-}
-
-#container {
- position: fixed;
- top: -200px;
- left: 5px;
- right: 5px;
- height: 100px;
- background: #fff9;
- backdrop-filter: blur(10px);
- border-radius: var(--border-radius);
- transition: top 0.2s ease;
- padding: 10px;
- display: grid;
- gap: 10px;
- box-shadow: var(--shadow);
-}
-
-#container.visible {
- top: 5px;
-}
-
-#title {
- font-size: 1.2em;
- align-content: center;
- padding-left: 5px;
- user-select: none;
-}
-
-#search-box {
- width: 100%;
- display: grid;
- grid-template-columns: auto 50px;
-}
-
-input {
- border-top-right-radius: 0px !important;
- border-bottom-right-radius: 0px !important;
-}
-
-button {
- width: 50px;
- border-top-left-radius: 0px !important;
- border-bottom-left-radius: 0px !important;
- height: 42px;
-}
diff --git a/static/widgets/search/index.js b/static/widgets/search/index.js
deleted file mode 100644
index b014cdd..0000000
--- a/static/widgets/search/index.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import icons from 'icons';
-import * as sfw from 'sfw';
-const { Div, Input, Button } = sfw.element.native;
-
-import stylesheet from './index.css';
-
-const css = await sfw.css.sheet(stylesheet);
-
-export default class Search extends sfw.element.Container {
- #container
- #search
-
- constructor() {
- super({ css });
-
- this.onsubmit = () => {}
- this.onhide = () => {}
-
- this.onclick = (e) => e.stopPropagation();
- this.hide = () => {
- this.#container.classList.remove('visible');
- document.removeEventListener('click', this.hide);
- this.onhide();
- };
-
- this.body.append(
- this.#container = Div.new({
- id: 'container',
- children: [
- Div.new({ innerText: 'Search', id: 'title' }),
- Div.new({
- id: 'search-box',
- children: [
- this.#search = Input.new({
- type: 'search',
- onsearch: () => this.submit(),
- onkeydown: (event) => {
- if (event.key === 'Enter') {
- this.submit();
- }
- }
- }),
- Button.new({
- children: [ icons.search ],
- onclick: () => this.submit(),
- }),
- ]
- })
- ]
- })
- );
- }
-
- submit() {
- this.onsubmit(this.#search.value);
- this.#search.blur();
- this.hide();
- }
-
- toggle() {
- this.#container.classList.toggle('visible');
-
- if (this.#container.classList.contains('visible')) {
- this.#search.focus()
- document.addEventListener('click', this.hide)
- }
- }
-}
diff --git a/static/widgets/upload-bar/index.css b/static/widgets/upload-bar/index.css
deleted file mode 100644
index 8ec1697..0000000
--- a/static/widgets/upload-bar/index.css
+++ /dev/null
@@ -1,41 +0,0 @@
-
-#container {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: calc(100% - 10px);
- height: 100px;
- background: #efefef99;
- backdrop-filter: blur(10px);
- border-radius: var(--border-radius);
- max-width: 500px;
- padding: 10px 20px;
- display: grid;
-}
-
-#files {
- background: #efefef;
- padding: 10px;
- border-radius: 20px;
- margin: auto;
- width: min-content;
- white-space: nowrap;
-}
-
-#inner-progress {
- width: 100%;
- height: 5px;
- border-radius: 5px;
- background: #efefef;
- overflow: hidden;
- margin: auto;
-}
-
-
-#progress {
- background: var(--primary);
- height: 100%;
- border-radius: 5px;
- transition: width 0.2s ease;
-}
diff --git a/static/widgets/upload-bar/index.js b/static/widgets/upload-bar/index.js
deleted file mode 100644
index f6d37b5..0000000
--- a/static/widgets/upload-bar/index.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import * as sfw from 'sfw';
-const { Div } = sfw.element.native;
-
-import stylesheet from './index.css';
-
-const css = await sfw.css.sheet(stylesheet);
-
-export default class UploadBar extends sfw.element.Container {
- #files_progress
- #inner_progress
- #container
-
- constructor() {
- super({ css });
-
- this.body.append(
- this.#container = Div.new({
- id: 'container',
- style: { display: 'none' },
- children: [
- this.#files_progress = Div.new({ id: 'files', innerText: 'Uploading...' }),
- Div.new({
- id: 'inner-progress',
- children: [
- this.#inner_progress = Div.new({ id: 'progress' }),
- ]
- })
- ]
- })
- );
- }
-
- set progress(progress) {
- this.#inner_progress.style.width = `${progress * 100}%`
- }
-
- hide() {
- this.#container.style.display = 'none';
- }
-
- show() {
- this.#container.style.display = '';
- }
-}