diff options
Diffstat (limited to 'static')
| -rw-r--r-- | static/api/profile.js | 7 | ||||
| -rw-r--r-- | static/api/rest.js | 2 | ||||
| -rw-r--r-- | static/index.js | 2 | ||||
| -rw-r--r-- | static/pages/image-viewer/index.css | 2 | ||||
| -rw-r--r-- | static/pages/image-viewer/index.js | 15 | ||||
| -rw-r--r-- | static/pages/settings/index.js | 8 | ||||
| -rw-r--r-- | static/widgets/editable/index.js | 11 | ||||
| -rw-r--r-- | static/widgets/image/index.css | 59 | ||||
| -rw-r--r-- | static/widgets/image/index.js | 30 |
9 files changed, 124 insertions, 12 deletions
diff --git a/static/api/profile.js b/static/api/profile.js index a9ee591..ec633e0 100644 --- a/static/api/profile.js +++ b/static/api/profile.js @@ -1 +1,8 @@ import * as rest from './rest.js'; + +export async function set(name, birthday) { + await rest.post('/api/profile/set', { + full_name: name, + birthday: birthday, + }); +} diff --git a/static/api/rest.js b/static/api/rest.js index b314615..6b14034 100644 --- a/static/api/rest.js +++ b/static/api/rest.js @@ -14,7 +14,7 @@ export function get(url) { return handle_fetch(fetch(url)); } -export async function post(url, body) { +export function post(url, body) { return handle_fetch(fetch(url, { method: 'POST', body: JSON.stringify(body), diff --git a/static/index.js b/static/index.js index c84aab9..d5d5c60 100644 --- a/static/index.js +++ b/static/index.js @@ -21,7 +21,7 @@ const reload = () => { image_viewer.clear(); api.images.list().then(images => { for (const image of images) { - image_viewer.add(`/api/image/load/${image.id}`); + image_viewer.add(image.id); } }); } diff --git a/static/pages/image-viewer/index.css b/static/pages/image-viewer/index.css index a1a9b76..4b1eb9b 100644 --- a/static/pages/image-viewer/index.css +++ b/static/pages/image-viewer/index.css @@ -8,7 +8,7 @@ padding: 10px; } -#container img { +#container sfw-image { margin: auto; max-width: 700px; width: 100%; diff --git a/static/pages/image-viewer/index.js b/static/pages/image-viewer/index.js index d28b3e1..0cf8598 100644 --- a/static/pages/image-viewer/index.js +++ b/static/pages/image-viewer/index.js @@ -1,6 +1,8 @@ import * as sfw from 'sfw'; const { Div, Img } = sfw.element.native; +import Image from '../../widgets/image/index.js'; + const css = await sfw.css(import.meta.url, './index.css') export default class ImageViewer extends sfw.element.Container { @@ -9,19 +11,16 @@ export default class ImageViewer extends sfw.element.Container { constructor() { super({ css }); + this.onnewer = () => {} + this.onolder = () => {} + this.body.append( this.#container = Div.new({ id: 'container' }) ); } - add(url) { - let image; - this.#container.append( - image = Img.new({ - className: 'hidden', - src: url, - onload: () => image.classList.remove('hidden') - })); + add(id) { + this.#container.append(Image.new({ id })) } clear() { diff --git a/static/pages/settings/index.js b/static/pages/settings/index.js index f316e8e..cc985a5 100644 --- a/static/pages/settings/index.js +++ b/static/pages/settings/index.js @@ -54,12 +54,14 @@ export default class SettingsView extends sfw.element.Container { }), this.#name = Editable.new({ title: 'Name', - value: '' + value: '', + onupdate: () => this.#update(), }), this.#birthday = Editable.new({ title: 'Birthday', type: 'date', value: '', + onupdate: () => this.#update(), }), Div.new({ id: 'logout', @@ -78,6 +80,10 @@ export default class SettingsView extends sfw.element.Container { ) } + #update() { + api.profile.set(this.#name.value, this.#birthday.value); + } + set profile(profile) { this.#profile = profile; diff --git a/static/widgets/editable/index.js b/static/widgets/editable/index.js index 8a72aff..0c93c4e 100644 --- a/static/widgets/editable/index.js +++ b/static/widgets/editable/index.js @@ -13,6 +13,8 @@ export default class Editable extends sfw.element.Container { constructor() { super({ css }); + this.onupdate = () => {}; + this.body.append( Div.new({ id: 'container', @@ -24,6 +26,7 @@ export default class Editable extends sfw.element.Container { if (e.key === 'Enter') { this.#input.readOnly = true; this.#update() + this.onupdate(); } }, }), @@ -33,6 +36,10 @@ export default class Editable extends sfw.element.Container { onclick: () => { this.#input.readOnly = !this.#input.readOnly; this.#update(); + + if (this.#input.readOnly) { + this.onupdate(); + } } }), ], @@ -59,6 +66,10 @@ export default class Editable extends sfw.element.Container { 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 new file mode 100644 index 0000000..f4e2dce --- /dev/null +++ b/static/widgets/image/index.css @@ -0,0 +1,59 @@ +#container { + position: relative; + background: var(--card-background); + height: 100%; +} + +#container img { + max-width: 700px; + width: 100%; + border-radius: var(--border-radius); + box-shadow: #223223aa 1px 1px 4px; + visibility: hidden; +} + +#container.loaded img { + visibility: visible; +} + +@keyframes loader { +} + +@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; +} diff --git a/static/widgets/image/index.js b/static/widgets/image/index.js new file mode 100644 index 0000000..ad77c4e --- /dev/null +++ b/static/widgets/image/index.js @@ -0,0 +1,30 @@ +import * as sfw from 'sfw'; +const { Div, Img } = sfw.element.native; + +const css = await sfw.css(import.meta.url, './index.css') + +export default class Image extends sfw.element.Container { + #container + #image + + constructor() { + super ({ css }) + + this.body.append( + this.#container = Div.new({ + id: 'container', + children: [ + this.#image = Img.new({ + onload: () => this.#container.classList.add('loaded'), + }), + Div.new({ id: 'loading' }) + ], + }) + ); + } + + set id(id) { + this.#container.classList.remove('loaded'); + this.#image.src = `/api/image/load/${id}`; + } +} |