@things-factory/gallery 10.1.247 → 10.1.248

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/package.json +3 -3
  2. package/dist-client/bootstrap.d.ts +0 -2
  3. package/dist-client/bootstrap.js +0 -26
  4. package/dist-client/bootstrap.js.map +0 -1
  5. package/dist-client/components/gallery-forms.d.ts +0 -31
  6. package/dist-client/components/gallery-forms.js +0 -223
  7. package/dist-client/components/gallery-forms.js.map +0 -1
  8. package/dist-client/components/gallery-saver-setting-let.d.ts +0 -11
  9. package/dist-client/components/gallery-saver-setting-let.js +0 -81
  10. package/dist-client/components/gallery-saver-setting-let.js.map +0 -1
  11. package/dist-client/components/gallery-show.d.ts +0 -46
  12. package/dist-client/components/gallery-show.js +0 -316
  13. package/dist-client/components/gallery-show.js.map +0 -1
  14. package/dist-client/components/gallery-uploader.d.ts +0 -57
  15. package/dist-client/components/gallery-uploader.js +0 -624
  16. package/dist-client/components/gallery-uploader.js.map +0 -1
  17. package/dist-client/components/gallery-viewer.d.ts +0 -30
  18. package/dist-client/components/gallery-viewer.js +0 -429
  19. package/dist-client/components/gallery-viewer.js.map +0 -1
  20. package/dist-client/index.d.ts +0 -1
  21. package/dist-client/index.js +0 -2
  22. package/dist-client/index.js.map +0 -1
  23. package/dist-client/pages/gallery-page.d.ts +0 -54
  24. package/dist-client/pages/gallery-page.js +0 -590
  25. package/dist-client/pages/gallery-page.js.map +0 -1
  26. package/dist-client/route.d.ts +0 -1
  27. package/dist-client/route.js +0 -9
  28. package/dist-client/route.js.map +0 -1
  29. package/dist-client/tsconfig.tsbuildinfo +0 -1
  30. package/dist-client/utils/gallery-api.d.ts +0 -99
  31. package/dist-client/utils/gallery-api.js +0 -46
  32. package/dist-client/utils/gallery-api.js.map +0 -1
  33. package/dist-client/utils/gallery-badge.d.ts +0 -4
  34. package/dist-client/utils/gallery-badge.js +0 -45
  35. package/dist-client/utils/gallery-badge.js.map +0 -1
  36. package/dist-client/utils/gallery-saver.d.ts +0 -6
  37. package/dist-client/utils/gallery-saver.js +0 -69
  38. package/dist-client/utils/gallery-saver.js.map +0 -1
  39. package/dist-client/utils/gallery-words.d.ts +0 -7
  40. package/dist-client/utils/gallery-words.js +0 -20
  41. package/dist-client/utils/gallery-words.js.map +0 -1
  42. package/dist-client/utils/photo-prep.d.ts +0 -10
  43. package/dist-client/utils/photo-prep.js +0 -102
  44. package/dist-client/utils/photo-prep.js.map +0 -1
  45. package/dist-server/attachment-reader.d.ts +0 -1
  46. package/dist-server/attachment-reader.js +0 -13
  47. package/dist-server/attachment-reader.js.map +0 -1
  48. package/dist-server/index.d.ts +0 -1
  49. package/dist-server/index.js +0 -11
  50. package/dist-server/index.js.map +0 -1
  51. package/dist-server/role-tasks.d.ts +0 -2
  52. package/dist-server/role-tasks.js +0 -15
  53. package/dist-server/role-tasks.js.map +0 -1
  54. package/dist-server/service/gallery/gallery-resolver.d.ts +0 -29
  55. package/dist-server/service/gallery/gallery-resolver.js +0 -613
  56. package/dist-server/service/gallery/gallery-resolver.js.map +0 -1
  57. package/dist-server/service/gallery/gallery-rules.d.ts +0 -90
  58. package/dist-server/service/gallery/gallery-rules.js +0 -182
  59. package/dist-server/service/gallery/gallery-rules.js.map +0 -1
  60. package/dist-server/service/gallery/gallery-service.d.ts +0 -37
  61. package/dist-server/service/gallery/gallery-service.js +0 -234
  62. package/dist-server/service/gallery/gallery-service.js.map +0 -1
  63. package/dist-server/service/gallery/gallery-types.d.ts +0 -65
  64. package/dist-server/service/gallery/gallery-types.js +0 -239
  65. package/dist-server/service/gallery/gallery-types.js.map +0 -1
  66. package/dist-server/service/gallery/gallery.d.ts +0 -84
  67. package/dist-server/service/gallery/gallery.js +0 -335
  68. package/dist-server/service/gallery/gallery.js.map +0 -1
  69. package/dist-server/service/gallery/index.d.ts +0 -4
  70. package/dist-server/service/gallery/index.js +0 -8
  71. package/dist-server/service/gallery/index.js.map +0 -1
  72. package/dist-server/service/index.d.ts +0 -7
  73. package/dist-server/service/index.js +0 -23
  74. package/dist-server/service/index.js.map +0 -1
  75. package/dist-server/tsconfig.tsbuildinfo +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"gallery-uploader.js","sourceRoot":"","sources":["../../client/components/gallery-uploader.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Posting photos (ADR-0165 decision 3) - and changing one's own post. Photos are all it needs; the caption, the tags\n * and the event are there to add. When the photos were taken is read from the first one, and the events near that day\n * are offered first - one press puts the post on one.\n */\nimport '@material/web/button/filled-button.js'\nimport '@material/web/button/text-button.js'\nimport '@material/web/icon/icon.js'\nimport '@operato/input/ox-input-file.js'\nimport '@operato/input/ox-input-select-buttons.js'\nimport '@operato/popup/ox-popup-actions.js'\n\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { CommonPopupStyles, PopupBodyStyles } from '@operato/styles'\nimport { isMobileDevice } from '@operato/utils'\n\nimport {\n galleryApi,\n galleryChanged,\n type EventChoice,\n type Photo,\n type Post,\n type Space\n} from '../utils/gallery-api.js'\nimport { day, reasonOf, t } from '../utils/gallery-words.js'\nimport { shrunk, takenAtOf } from '../utils/photo-prep.js'\n\nconst MAX_PHOTOS = 20\nconst MAX_CAPTION = 500\nconst MAX_TAGS = 10\nconst MAX_TAG = 30\n/* The events shown before 「more」 - the near ones are among them. */\nconst FIRST_CHOICES = 4\n\ntype Added = { file: File; url: string }\n\n/** yyyy-mm-dd of a date in the reader's own time. */\nconst dateText = (value: Date) =>\n `${value.getFullYear()}-${String(value.getMonth() + 1).padStart(2, '0')}-${String(value.getDate()).padStart(2, '0')}`\n\n@customElement('gallery-uploader')\nexport class GalleryUploader extends localize(i18next)(LitElement) {\n static styles = [\n CommonPopupStyles,\n PopupBodyStyles,\n css`\n :host {\n height: 100%;\n }\n .body {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-large, 12px);\n }\n h4 {\n margin: 0 0 var(--spacing-small, 4px);\n font-size: var(--ui-t-small, 12px);\n font-weight: 600;\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n .photos {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));\n gap: var(--spacing-small, 4px);\n }\n .photo {\n position: relative;\n aspect-ratio: 1;\n border-radius: var(--border-radius, 4px);\n overflow: hidden;\n background: var(--md-sys-color-surface-container-high);\n }\n .photo img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n display: block;\n }\n .photo button {\n position: absolute;\n top: 2px;\n inset-inline-end: 2px;\n display: inline-flex;\n padding: 2px;\n border: 0;\n border-radius: 50%;\n background: rgb(0 0 0 / 55%);\n color: #fff;\n cursor: pointer;\n }\n .photo button md-icon {\n --md-icon-size: 16px;\n }\n .add {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 2px;\n aspect-ratio: 1;\n border: 1px dashed var(--ui-line, var(--md-sys-color-outline));\n border-radius: var(--border-radius, 4px);\n background: none;\n color: var(--md-sys-color-primary);\n font: inherit;\n font-size: var(--ui-t-small, 12px);\n cursor: pointer;\n }\n .add[disabled] {\n opacity: 0.4;\n cursor: default;\n }\n ox-input-file {\n display: contents;\n }\n textarea,\n input {\n box-sizing: border-box;\n width: 100%;\n font: inherit;\n font-size: var(--ui-t-body, 14px);\n padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: var(--border-radius, 4px);\n background: var(--md-sys-color-surface);\n color: var(--md-sys-color-on-surface);\n }\n textarea {\n min-height: 64px;\n resize: vertical;\n }\n input[type='date'] {\n width: auto;\n }\n .count {\n text-align: end;\n font-size: var(--ui-t-small, 12px);\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n .refusal {\n font-size: var(--ui-t-small, 12px);\n color: var(--md-sys-color-error);\n }\n .chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-small, 4px);\n align-items: center;\n }\n .chip {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 2px var(--spacing-medium, 8px);\n border: 1px solid var(--ui-line-soft, var(--md-sys-color-outline-variant));\n border-radius: 999px;\n background: none;\n color: var(--md-sys-color-on-surface);\n font: inherit;\n font-size: var(--ui-t-small, 12px);\n line-height: 1.6;\n cursor: pointer;\n }\n .chip[aria-pressed='true'] {\n border-color: var(--md-sys-color-primary);\n background: var(--md-sys-color-primary-container);\n color: var(--md-sys-color-on-primary-container);\n }\n .chip md-icon {\n --md-icon-size: 14px;\n }\n .chip .near {\n color: var(--md-sys-color-primary);\n }\n .tag-input {\n flex: 1;\n min-width: 120px;\n width: auto;\n border: 0;\n padding: 2px 0;\n background: none;\n }\n .tag-input:focus {\n outline: none;\n }\n .tags {\n padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: var(--border-radius, 4px);\n }\n .suggest {\n margin-top: var(--spacing-small, 4px);\n }\n .suggest .chip {\n border-style: dashed;\n }\n .muted {\n font-size: var(--ui-t-small, 12px);\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n .row {\n display: flex;\n flex-wrap: wrap;\n gap: var(--spacing-large, 12px);\n align-items: flex-end;\n }\n `\n ]\n\n /** The post being changed - nothing when posting a new one. */\n @property({ attribute: false }) post?: Post\n /** The photos the page picked before the window opened. */\n @property({ attribute: false }) files: File[] = []\n /** Where a new post goes - the screen it was opened from. */\n @property() space: Space = 'COMPANY'\n @property() eventId?: string | null\n\n @state() private added: Added[] = []\n @state() private kept: Photo[] = []\n @state() private caption = ''\n @state() private tags: string[] = []\n @state() private tagText = ''\n /** Why the tag being typed was not taken - said under the tags, the text kept so it can be shortened. */\n @state() private tagRefusal = ''\n @state() private suggestions: { tag: string; count: number }[] = []\n @state() private chosenSpace: Space = 'COMPANY'\n /** A post of the own gallery is the person's alone until shared (decision 2) - off when posting. */\n @state() private shared = false\n @state() private chosenEvent: string | null = null\n @state() private takenOn = dateText(new Date())\n @state() private choices: EventChoice[] = []\n @state() private allChoices = false\n @state() private progress?: number\n @state() private busy = false\n\n @query('#pick') private picker!: any\n @query('#shoot') private camera!: any\n\n private suggestTimer?: ReturnType<typeof setTimeout>\n\n render() {\n const total = this.kept.length + this.added.length\n const full = total >= MAX_PHOTOS\n const company = this.chosenSpace === 'COMPANY'\n const shown = this.allChoices ? this.choices : this.choices.slice(0, FIRST_CHOICES)\n const chosen = this.choices.find(one => one.id === this.chosenEvent)\n return html`<div class=\"body\">\n <section>\n <div class=\"photos\">\n ${this.kept.map(\n one =>\n html`<div class=\"photo\">\n <img src=${one.thumbnail || one.fullpath} alt=\"\" />\n <button\n aria-label=${t('gallery.button.remove-photo')}\n @click=${() => (this.kept = this.kept.filter(other => other !== one))}\n >\n <md-icon>close</md-icon>\n </button>\n </div>`\n )}\n ${this.added.map(\n one =>\n html`<div class=\"photo\">\n <img src=${one.url} alt=\"\" />\n <button aria-label=${t('gallery.button.remove-photo')} @click=${() => this.drop(one)}>\n <md-icon>close</md-icon>\n </button>\n </div>`\n )}\n <button class=\"add\" ?disabled=${full || this.busy} @click=${() => this.picker?.pick()}>\n <md-icon>add_photo_alternate</md-icon>${t('gallery.button.add-photos')}\n </button>\n ${\n isMobileDevice()\n ? html`<button class=\"add\" ?disabled=${full || this.busy} @click=${() => this.camera?.pick()}>\n <md-icon>photo_camera</md-icon>${t('gallery.button.shoot-more')}\n </button>`\n : nothing\n }\n </div>\n <ox-input-file\n id=\"pick\"\n quiet\n outside-trigger\n hide-filelist\n multiple\n accept=\"image/*\"\n .progress=${this.progress}\n @change=${(e: CustomEvent) => this.take(e)}\n ></ox-input-file>\n <ox-input-file\n id=\"shoot\"\n quiet\n outside-trigger\n hide-filelist\n accept=\"image/*\"\n capture=\"environment\"\n @change=${(e: CustomEvent) => this.take(e)}\n ></ox-input-file>\n ${full ? html`<div class=\"muted\">${t('gallery.text.photos-full', { count: MAX_PHOTOS })}</div>` : nothing}\n </section>\n\n <section>\n <textarea\n maxlength=${MAX_CAPTION}\n placeholder=${t('gallery.text.caption-placeholder')}\n .value=${this.caption}\n @input=${(e: any) => (this.caption = e.target.value)}\n ></textarea>\n ${this.caption.length > MAX_CAPTION * 0.8 ? html`<div class=\"count\">${this.caption.length} / ${MAX_CAPTION}</div>` : nothing}\n </section>\n\n <section>\n <h4>${t('gallery.field.tags')}</h4>\n <div class=\"chips tags\">\n ${this.tags.map(tag => html`<span class=\"chip\">#${tag}<md-icon role=\"button\" aria-label=${t('gallery.button.remove-tag')} @click=${() => (this.tags = this.tags.filter(one => one !== tag))}>close</md-icon></span>`)}\n ${\n this.tags.length < MAX_TAGS\n ? html`<input\n class=\"tag-input\"\n .value=${this.tagText}\n placeholder=${this.tags.length ? '' : t('gallery.text.tag-placeholder')}\n @input=${(e: any) => this.typeTag(e.target.value)}\n @keydown=${(e: KeyboardEvent) => this.tagKey(e)}\n @blur=${() => this.addTag(this.tagText)}\n />`\n : nothing\n }\n </div>\n ${this.tagRefusal ? html`<div class=\"refusal\" role=\"alert\">${this.tagRefusal}</div>` : nothing}\n ${\n this.suggestions.length\n ? html`<div class=\"chips suggest\">\n ${this.suggestions.filter(one => !this.tags.some(tag => tag.toLowerCase() === one.tag.toLowerCase())).map(one => html`<button class=\"chip\" @mousedown=${(e: Event) => e.preventDefault()} @click=${() => this.addTag(one.tag)}>#${one.tag}</button>`)}\n </div>`\n : nothing\n }\n </section>\n\n <section class=\"row\">\n <div>\n <h4>${t('gallery.field.space')}</h4>\n <ox-input-select-buttons\n .options=${(['COMPANY', 'PERSONAL'] as Space[]).map(space => ({ value: space, display: t(`gallery.space.${space}`) }))}\n .value=${this.chosenSpace}\n @change=${(e: CustomEvent) => (e.detail ? this.chooseSpace(e.detail as Space) : ((e.target as any).value = this.chosenSpace))}\n ></ox-input-select-buttons>\n </div>\n <div>\n <h4>${t('gallery.field.taken-on')}</h4>\n <input type=\"date\" .value=${this.takenOn} @change=${(e: any) => this.changeDay(e.target.value)} />\n </div>\n </section>\n\n ${\n company\n ? html`<section>\n <h4>${t('gallery.field.event')}</h4>\n <div class=\"chips\">\n <button\n class=\"chip\"\n aria-pressed=${String(!this.chosenEvent)}\n @click=${() => (this.chosenEvent = null)}\n >\n ${t('gallery.text.no-event')}\n </button>\n ${chosen && !shown.includes(chosen) ? this.choiceChip(chosen) : nothing}\n ${shown.map(one => this.choiceChip(one))}\n ${\n this.choices.length > FIRST_CHOICES && !this.allChoices\n ? html`<button class=\"chip\" @click=${() => (this.allChoices = true)}>\n ${t('gallery.button.more-events', { count: this.choices.length - FIRST_CHOICES })}\n </button>`\n : nothing\n }\n </div>\n </section>`\n : html`<section>\n <h4>${t('gallery.field.shared')}</h4>\n <ox-input-select-buttons\n .options=${[\n { value: 'me', display: t('gallery.text.only-me') },\n { value: 'everyone', display: t('gallery.text.everyone') }\n ]}\n .value=${this.shared ? 'everyone' : 'me'}\n @change=${(e: CustomEvent) => (e.detail ? (this.shared = e.detail === 'everyone') : ((e.target as any).value = this.shared ? 'everyone' : 'me'))}\n ></ox-input-select-buttons>\n <div class=\"muted\">${t(this.shared ? 'gallery.text.shared-note' : 'gallery.text.only-me-note')}</div>\n </section>`\n }\n </div>\n <ox-popup-actions>\n <md-text-button slot=\"cancel\" ?disabled=${this.busy} @click=${() => this.close()}\n >${t('gallery.button.cancel')}</md-text-button\n >\n <md-filled-button slot=\"confirm\" ?disabled=${this.busy || total < 1} @click=${() => this.save()}\n >${this.post ? t('gallery.button.save') : t('gallery.button.post-count', { count: total })}</md-filled-button\n >\n </ox-popup-actions>`\n }\n\n private choiceChip(one: EventChoice) {\n return html`<button\n class=\"chip\"\n aria-pressed=${String(this.chosenEvent === one.id)}\n @click=${() => (this.chosenEvent = one.id)}\n >\n ${one.near ? html`<md-icon class=\"near\">event_available</md-icon>` : nothing}${one.name}<span class=\"muted\"\n >· ${day(one.startAt)}</span\n >\n </button>`\n }\n\n async firstUpdated() {\n const post = this.post\n if (post) {\n this.kept = [...post.photos]\n this.caption = post.caption ?? ''\n this.tags = [...(post.tags ?? [])]\n this.chosenSpace = post.space\n this.shared = post.shared\n this.chosenEvent = post.event?.id ?? null\n this.takenOn = dateText(new Date(post.takenAt))\n } else {\n this.chosenSpace = this.eventId ? 'COMPANY' : this.space\n this.chosenEvent = this.eventId ?? null\n }\n await this.add(this.files ?? [])\n await this.loadChoices()\n }\n\n disconnectedCallback() {\n for (const one of this.added) URL.revokeObjectURL(one.url)\n clearTimeout(this.suggestTimer)\n super.disconnectedCallback()\n }\n\n private async take(e: CustomEvent) {\n const picked = [...((e.detail as File[]) ?? [])]\n /* The picker's own reset says `change` again, with nothing - that one is let go. */\n if (!picked.length) return\n ;(e.target as any).reset?.()\n const before = this.kept.length + this.added.length\n await this.add(picked)\n /* The first photo says the day - the events near it come first. */\n if (!before && !this.post) await this.loadChoices()\n }\n\n private async add(files: File[]) {\n const room = MAX_PHOTOS - this.kept.length - this.added.length\n const photos = files\n .filter(file => /^image\\//i.test(file.type) || /\\.(jpe?g|png|gif|webp|heic|heif)$/i.test(file.name))\n .slice(0, Math.max(0, room))\n if (photos.length < files.length)\n notify({ level: 'warn', message: t('gallery.text.photos-skipped', { count: files.length - photos.length }) })\n if (!photos.length) return\n const first = !this.kept.length && !this.added.length && !this.post\n this.added = [...this.added, ...photos.map(file => ({ file, url: URL.createObjectURL(file) }))]\n if (first) {\n const takenAt = await takenAtOf(photos[0])\n if (takenAt) this.takenOn = dateText(takenAt)\n }\n }\n\n private drop(one: Added) {\n URL.revokeObjectURL(one.url)\n this.added = this.added.filter(other => other !== one)\n }\n\n private takenAt(): string {\n const [y, m, d] = this.takenOn.split('-').map(Number)\n const now = new Date()\n /* A day chosen without its hour keeps the hour it was posted - today's photo is not dated midnight. */\n const at = y ? new Date(y, m - 1, d, now.getHours(), now.getMinutes()) : now\n return at.toISOString()\n }\n\n private async loadChoices() {\n try {\n /* Offered, not chosen: the events near that day come first, and one press puts the post on one. */\n this.choices = await galleryApi.eventChoices(this.takenAt())\n } catch {\n this.choices = []\n }\n }\n\n private async changeDay(value: string) {\n if (!value) return\n this.takenOn = value\n await this.loadChoices()\n }\n\n private chooseSpace(space: Space) {\n this.chosenSpace = space\n if (space === 'PERSONAL') this.chosenEvent = null\n }\n\n private typeTag(value: string) {\n if (/[,\\s]$/.test(value) && value.trim()) {\n this.addTag(value)\n return\n }\n this.tagText = value\n clearTimeout(this.suggestTimer)\n this.suggestTimer = setTimeout(async () => {\n try {\n this.suggestions = await galleryApi.tags(this.tagText)\n } catch {\n this.suggestions = []\n }\n }, 200)\n }\n\n private tagKey(e: KeyboardEvent) {\n if (e.isComposing) return\n if (e.key === 'Enter') {\n e.preventDefault()\n this.addTag(this.tagText)\n } else if (e.key === 'Backspace' && !this.tagText && this.tags.length) {\n this.tags = this.tags.slice(0, -1)\n }\n }\n\n /** Takes the typed tag, or says why not and keeps it - a longer tag was cut at 30 without a word (2026-10-30). */\n private addTag(raw: string): boolean {\n const tag = raw.replace(/[,]/g, ' ').trim().replace(/^#+/, '').replace(/\\s+/g, ' ').trim()\n if (tag.length > MAX_TAG) {\n this.tagRefusal = t('gallery.text.tag-too-long-typed', { max: MAX_TAG, length: tag.length })\n return false\n }\n this.tagRefusal = ''\n this.tagText = ''\n if (!tag || this.tags.length >= MAX_TAGS || this.tags.some(one => one.toLowerCase() === tag.toLowerCase())) return true\n this.tags = [...this.tags, tag]\n return true\n }\n\n private async save() {\n if (!this.addTag(this.tagText)) return\n this.busy = true\n try {\n const files = await Promise.all(this.added.map(one => shrunk(one.file)))\n const input = {\n space: this.chosenSpace,\n shared: this.chosenSpace === 'PERSONAL' && this.shared,\n caption: this.caption.trim(),\n takenAt: this.takenAt(),\n tags: this.tags,\n eventId: this.chosenSpace === 'COMPANY' ? this.chosenEvent : null\n }\n const uploading = (fraction: number) => (this.progress = fraction)\n const post = this.post\n ? await galleryApi.update(\n this.post.id,\n input,\n files,\n this.post.photos.filter(one => !this.kept.includes(one)).map(one => one.id),\n uploading\n )\n : await galleryApi.create(input, files, uploading)\n notify({ message: this.post ? t('gallery.text.saved') : t('gallery.text.posted') })\n galleryChanged()\n this.dispatchEvent(new CustomEvent('gallery-posted', { detail: post, bubbles: true, composed: true }))\n this.close()\n } catch (error) {\n notify({ level: 'error', message: reasonOf(error) })\n } finally {\n this.progress = undefined\n this.busy = false\n }\n }\n\n private close() {\n this.dispatchEvent(new CustomEvent('done', { bubbles: true, composed: true }))\n }\n}\n"]}
@@ -1,30 +0,0 @@
1
- import '@material/web/button/filled-button.js';
2
- import '@material/web/button/text-button.js';
3
- import '@material/web/icon/icon.js';
4
- import '@operato/popup/ox-popup-actions.js';
5
- import { LitElement, nothing } from 'lit';
6
- import { type Post } from '../utils/gallery-api.js';
7
- declare const GalleryViewer_base: (new (...args: any[]) => LitElement) & typeof LitElement;
8
- export declare class GalleryViewer extends GalleryViewer_base {
9
- static styles: import("lit").CSSResult[];
10
- post: Post;
11
- private index;
12
- private likers?;
13
- private hiding;
14
- private reason;
15
- private burst;
16
- private busy;
17
- render(): typeof nothing | import("lit-html").TemplateResult<1>;
18
- private replace;
19
- /** Likes it, or takes the like back. A double press on the photo only likes - it never takes one back. */
20
- private like;
21
- private showLikers;
22
- private edit;
23
- private deletePost;
24
- private hide;
25
- private unhide;
26
- private go;
27
- /** The next step - a page to go to, the post to change, or the photo to see large - goes as the popup's result: the page takes it once the popup is gone. */
28
- private close;
29
- }
30
- export {};
@@ -1,429 +0,0 @@
1
- import { __decorate, __metadata } from "tslib";
2
- /*
3
- * One post seen large (ADR-0165 decisions 4-6): its photos one by one - and across the whole screen (decision 9) - the like (the heart, or a double press on the
4
- * photo), who posted it and when, its event and tags - each opens the gallery narrowed to it. Its owner changes or
5
- * deletes it here; a moderator hides it here, with the reason, or shows it again. Where to go next is the popup's result
6
- * - a popup closes by going back in the history, so a page opened before it is gone would be gone with it.
7
- */
8
- import '@material/web/button/filled-button.js';
9
- import '@material/web/button/text-button.js';
10
- import '@material/web/icon/icon.js';
11
- import '@operato/popup/ox-popup-actions.js';
12
- import { css, html, LitElement, nothing } from 'lit';
13
- import { customElement, property, state } from 'lit/decorators.js';
14
- import { i18next, localize } from '@operato/i18n';
15
- import { notify } from '@operato/layout';
16
- import { OxPrompt } from '@operato/popup/ox-prompt.js';
17
- import { CommonPopupStyles, PopupBodyStyles } from '@operato/styles';
18
- import { galleryApi, galleryChanged } from '../utils/gallery-api.js';
19
- import { day, days, reasonOf, t } from '../utils/gallery-words.js';
20
- let GalleryViewer = class GalleryViewer extends localize(i18next)(LitElement) {
21
- constructor() {
22
- super(...arguments);
23
- this.index = 0;
24
- this.hiding = false;
25
- this.reason = '';
26
- this.burst = 0;
27
- this.busy = false;
28
- }
29
- static { this.styles = [
30
- CommonPopupStyles,
31
- PopupBodyStyles,
32
- css `
33
- :host {
34
- height: 100%;
35
- }
36
- .body {
37
- display: flex;
38
- flex-direction: column;
39
- gap: var(--spacing-medium, 8px);
40
- }
41
- .stage {
42
- position: relative;
43
- display: flex;
44
- align-items: center;
45
- justify-content: center;
46
- min-height: 240px;
47
- max-height: 62vh;
48
- background: var(--md-sys-color-surface-container-highest);
49
- border-radius: var(--border-radius, 4px);
50
- overflow: hidden;
51
- user-select: none;
52
- }
53
- .stage img {
54
- max-width: 100%;
55
- max-height: 62vh;
56
- object-fit: contain;
57
- display: block;
58
- }
59
- .stage .turn {
60
- position: absolute;
61
- top: 50%;
62
- transform: translateY(-50%);
63
- display: inline-flex;
64
- padding: 4px;
65
- border: 0;
66
- border-radius: 50%;
67
- background: rgb(0 0 0 / 45%);
68
- color: #fff;
69
- cursor: pointer;
70
- }
71
- .stage .previous {
72
- inset-inline-start: var(--spacing-small, 4px);
73
- }
74
- .stage .next {
75
- inset-inline-end: var(--spacing-small, 4px);
76
- }
77
- .stage .large {
78
- position: absolute;
79
- top: var(--spacing-small, 4px);
80
- inset-inline-end: var(--spacing-small, 4px);
81
- display: inline-flex;
82
- padding: 4px;
83
- border: 0;
84
- border-radius: 50%;
85
- background: rgb(0 0 0 / 45%);
86
- color: #fff;
87
- cursor: pointer;
88
- }
89
- .stage .index {
90
- position: absolute;
91
- bottom: var(--spacing-small, 4px);
92
- inset-inline-end: var(--spacing-medium, 8px);
93
- padding: 0 6px;
94
- border-radius: 999px;
95
- background: rgb(0 0 0 / 45%);
96
- color: #fff;
97
- font-size: var(--ui-t-small, 12px);
98
- }
99
- .burst {
100
- position: absolute;
101
- --md-icon-size: 72px;
102
- color: #fff;
103
- opacity: 0.9;
104
- animation: burst 600ms ease-out forwards;
105
- pointer-events: none;
106
- }
107
- @keyframes burst {
108
- from {
109
- transform: scale(0.6);
110
- opacity: 0.9;
111
- }
112
- to {
113
- transform: scale(1.3);
114
- opacity: 0;
115
- }
116
- }
117
- .line {
118
- display: flex;
119
- flex-wrap: wrap;
120
- align-items: center;
121
- gap: var(--spacing-small, 4px) var(--spacing-medium, 8px);
122
- font-size: var(--ui-t-small, 12px);
123
- color: var(--ui-muted, var(--md-sys-color-on-surface-variant));
124
- }
125
- .heart {
126
- display: inline-flex;
127
- align-items: center;
128
- gap: 2px;
129
- padding: 0;
130
- border: 0;
131
- background: none;
132
- color: var(--md-sys-color-on-surface);
133
- font: inherit;
134
- font-size: var(--ui-t-body, 14px);
135
- cursor: pointer;
136
- }
137
- /* The app's icons are drawn filled; an empty heart says not liked yet. */
138
- .heart md-icon {
139
- --md-icon-size: 22px;
140
- font-variation-settings: 'FILL' 0;
141
- }
142
- .heart[aria-pressed='true'] md-icon {
143
- color: var(--md-sys-color-error);
144
- font-variation-settings: 'FILL' 1;
145
- }
146
- .link {
147
- display: inline-flex;
148
- align-items: center;
149
- gap: 2px;
150
- padding: 0;
151
- border: 0;
152
- background: none;
153
- color: var(--md-sys-color-primary);
154
- font: inherit;
155
- cursor: pointer;
156
- }
157
- .link:hover {
158
- text-decoration: underline;
159
- }
160
- .link md-icon {
161
- --md-icon-size: 14px;
162
- }
163
- .caption {
164
- margin: 0;
165
- font-size: var(--ui-t-body, 14px);
166
- line-height: 1.6;
167
- white-space: pre-wrap;
168
- overflow-wrap: anywhere;
169
- color: var(--md-sys-color-on-surface);
170
- }
171
- .hidden {
172
- padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);
173
- border-radius: var(--border-radius, 4px);
174
- background: var(--md-sys-color-error-container);
175
- color: var(--md-sys-color-on-error-container);
176
- font-size: var(--ui-t-small, 12px);
177
- }
178
- .likers {
179
- font-size: var(--ui-t-small, 12px);
180
- color: var(--ui-muted, var(--md-sys-color-on-surface-variant));
181
- }
182
- textarea {
183
- box-sizing: border-box;
184
- width: 100%;
185
- min-height: 56px;
186
- font: inherit;
187
- padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);
188
- border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));
189
- border-radius: var(--border-radius, 4px);
190
- background: var(--md-sys-color-surface);
191
- color: var(--md-sys-color-on-surface);
192
- }
193
- .spacer {
194
- margin-inline-end: auto;
195
- }
196
- `
197
- ]; }
198
- render() {
199
- const post = this.post;
200
- if (!post)
201
- return nothing;
202
- const photo = post.photos[this.index];
203
- const many = post.photos.length > 1;
204
- return html `<div class="body">
205
- ${post.hiddenAt ? html `<div class="hidden">${t('gallery.text.hidden-note')}${post.hiddenReason ? ` · ${post.hiddenReason}` : ''}</div>` : nothing}
206
- <div class="stage" @dblclick=${() => this.like(true, true)}>
207
- ${photo ? html `<img src=${photo.fullpath} alt=${post.caption ?? ''} />` : nothing}
208
- ${photo ? html `<button class="large" aria-label=${t('gallery.button.large')} title=${t('gallery.button.large')} @click=${() => this.close({ show: { postId: post.id, index: this.index } })}><md-icon>fullscreen</md-icon></button>` : nothing}
209
- ${this.burst ? html `<md-icon class="burst" style="font-variation-settings:'FILL' 1">favorite</md-icon>` : nothing}
210
- ${many
211
- ? html `${this.index > 0 ? html `<button class="turn previous" aria-label=${t('gallery.button.previous')} @click=${() => (this.index -= 1)}><md-icon>chevron_left</md-icon></button>` : nothing}
212
- ${this.index < post.photos.length - 1 ? html `<button class="turn next" aria-label=${t('gallery.button.next')} @click=${() => (this.index += 1)}><md-icon>chevron_right</md-icon></button>` : nothing}
213
- <span class="index">${this.index + 1} / ${post.photos.length}</span>`
214
- : nothing}
215
- </div>
216
-
217
- <div class="line">
218
- <button
219
- class="heart"
220
- aria-pressed=${String(post.liked)}
221
- aria-label=${t('gallery.button.like')}
222
- ?disabled=${this.busy}
223
- @click=${() => this.like(!post.liked)}
224
- >
225
- <md-icon>favorite</md-icon>
226
- </button>
227
- <button class="link" ?disabled=${!post.likeCount} @click=${() => this.showLikers()}>
228
- ${t('gallery.text.like-count', { count: post.likeCount })}
229
- </button>
230
- <span class="spacer"></span>
231
- <button class="link" @click=${() => this.go(`gallery-page?author=${post.creator?.id}`)}>
232
- ${post.creator?.name ?? ''}
233
- </button>
234
- <span>${day(post.takenAt)}</span>
235
- </div>
236
- ${this.likers ? html `<div class="likers">${this.likers.map(one => one.name).join(', ')}</div>` : nothing}
237
- ${post.caption ? html `<p class="caption">${post.caption}</p>` : nothing}
238
-
239
- <div class="line">
240
- ${post.event
241
- ? html `<button class="link" @click=${() => this.go(`gallery-page?event=${post.event.id}`)}>
242
- <md-icon>event</md-icon>${post.event.name} · ${days(post.event.startAt, post.event.endAt)}
243
- </button>`
244
- : nothing}
245
- ${(post.tags ?? []).map(tag => html `<button class="link" @click=${() => this.go(`gallery-page?tag=${encodeURIComponent(tag)}`)}>#${tag}</button>`)}
246
- ${post.space === 'PERSONAL' ? html `<span>${t('gallery.space.PERSONAL')}${post.shared ? '' : ` · ${t('gallery.text.only-me')}`}</span>` : nothing}
247
- </div>
248
-
249
- ${this.hiding
250
- ? html `<div>
251
- <textarea
252
- maxlength="200"
253
- placeholder=${t('gallery.text.hide-reason')}
254
- .value=${this.reason}
255
- @input=${(e) => (this.reason = e.target.value)}
256
- ></textarea>
257
- </div>`
258
- : nothing}
259
- </div>
260
- <ox-popup-actions>
261
- ${post.editable
262
- ? html `<md-text-button ?disabled=${this.busy} @click=${() => this.edit()}
263
- >${t('gallery.button.edit')}</md-text-button
264
- >
265
- <md-text-button ?disabled=${this.busy} @click=${() => this.deletePost()}
266
- >${t('gallery.button.delete')}</md-text-button
267
- >`
268
- : nothing}
269
- ${post.moderatable && !this.hiding
270
- ? post.hiddenAt
271
- ? html `<md-text-button ?disabled=${this.busy} @click=${() => this.unhide()}
272
- >${t('gallery.button.unhide')}</md-text-button
273
- >`
274
- : html `<md-text-button ?disabled=${this.busy} @click=${() => (this.hiding = true)}
275
- >${t('gallery.button.hide')}</md-text-button
276
- >`
277
- : nothing}
278
- ${this.hiding
279
- ? html `<md-text-button slot="cancel" @click=${() => (this.hiding = false)}
280
- >${t('gallery.button.cancel')}</md-text-button
281
- >
282
- <md-filled-button
283
- slot="confirm"
284
- ?disabled=${this.busy || !this.reason.trim()}
285
- @click=${() => this.hide()}
286
- >${t('gallery.button.hide')}</md-filled-button
287
- >`
288
- : html `<md-filled-button slot="confirm" @click=${() => this.close()}
289
- >${t('gallery.button.close')}</md-filled-button
290
- >`}
291
- </ox-popup-actions>`;
292
- }
293
- replace(post) {
294
- this.post = post;
295
- this.index = Math.min(this.index, Math.max(0, post.photos.length - 1));
296
- galleryChanged();
297
- }
298
- /** Likes it, or takes the like back. A double press on the photo only likes - it never takes one back. */
299
- async like(like, fromPhoto = false) {
300
- const post = this.post;
301
- if (fromPhoto) {
302
- this.burst++;
303
- setTimeout(() => (this.burst = 0), 600);
304
- if (post.liked)
305
- return;
306
- }
307
- this.busy = true;
308
- try {
309
- const state = await galleryApi.like(post.id, like);
310
- this.post = { ...post, likeCount: state.likeCount, liked: state.liked };
311
- if (this.likers)
312
- this.likers = await galleryApi.likers(post.id);
313
- this.dispatchEvent(new CustomEvent('gallery-liked', { detail: this.post, bubbles: true, composed: true }));
314
- }
315
- catch (error) {
316
- notify({ level: 'error', message: reasonOf(error) });
317
- }
318
- finally {
319
- this.busy = false;
320
- }
321
- }
322
- async showLikers() {
323
- if (this.likers) {
324
- this.likers = undefined;
325
- return;
326
- }
327
- try {
328
- this.likers = await galleryApi.likers(this.post.id);
329
- }
330
- catch (error) {
331
- notify({ level: 'error', message: reasonOf(error) });
332
- }
333
- }
334
- edit() {
335
- this.close({ edit: this.post });
336
- }
337
- async deletePost() {
338
- const sure = await OxPrompt.open({
339
- title: t('gallery.button.delete'),
340
- text: t('gallery.text.delete-confirm'),
341
- confirmButton: { text: t('gallery.button.delete') },
342
- cancelButton: { text: t('gallery.button.cancel') }
343
- });
344
- if (!sure)
345
- return;
346
- this.busy = true;
347
- try {
348
- await galleryApi.remove(this.post.id);
349
- notify({ message: t('gallery.text.deleted') });
350
- galleryChanged();
351
- this.close();
352
- }
353
- catch (error) {
354
- notify({ level: 'error', message: reasonOf(error) });
355
- }
356
- finally {
357
- this.busy = false;
358
- }
359
- }
360
- async hide() {
361
- this.busy = true;
362
- try {
363
- const own = this.post.editable;
364
- this.replace(await galleryApi.hide(this.post.id, this.reason.trim()));
365
- this.hiding = false;
366
- this.reason = '';
367
- /* Its owner is told - unless the one hiding it is its owner. */
368
- notify({ message: own ? t('gallery.text.hidden-own') : t('gallery.text.hidden-done') });
369
- }
370
- catch (error) {
371
- notify({ level: 'error', message: reasonOf(error) });
372
- }
373
- finally {
374
- this.busy = false;
375
- }
376
- }
377
- async unhide() {
378
- this.busy = true;
379
- try {
380
- this.replace(await galleryApi.unhide(this.post.id));
381
- }
382
- catch (error) {
383
- notify({ level: 'error', message: reasonOf(error) });
384
- }
385
- finally {
386
- this.busy = false;
387
- }
388
- }
389
- go(address) {
390
- this.close({ go: address });
391
- }
392
- /** The next step - a page to go to, the post to change, or the photo to see large - goes as the popup's result: the page takes it once the popup is gone. */
393
- close(next) {
394
- this.dispatchEvent(new CustomEvent('done', { detail: next, bubbles: true, composed: true }));
395
- }
396
- };
397
- __decorate([
398
- property({ attribute: false }),
399
- __metadata("design:type", Object)
400
- ], GalleryViewer.prototype, "post", void 0);
401
- __decorate([
402
- state(),
403
- __metadata("design:type", Object)
404
- ], GalleryViewer.prototype, "index", void 0);
405
- __decorate([
406
- state(),
407
- __metadata("design:type", Array)
408
- ], GalleryViewer.prototype, "likers", void 0);
409
- __decorate([
410
- state(),
411
- __metadata("design:type", Object)
412
- ], GalleryViewer.prototype, "hiding", void 0);
413
- __decorate([
414
- state(),
415
- __metadata("design:type", Object)
416
- ], GalleryViewer.prototype, "reason", void 0);
417
- __decorate([
418
- state(),
419
- __metadata("design:type", Object)
420
- ], GalleryViewer.prototype, "burst", void 0);
421
- __decorate([
422
- state(),
423
- __metadata("design:type", Object)
424
- ], GalleryViewer.prototype, "busy", void 0);
425
- GalleryViewer = __decorate([
426
- customElement('gallery-viewer')
427
- ], GalleryViewer);
428
- export { GalleryViewer };
429
- //# sourceMappingURL=gallery-viewer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gallery-viewer.js","sourceRoot":"","sources":["../../client/components/gallery-viewer.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * One post seen large (ADR-0165 decisions 4-6): its photos one by one - and across the whole screen (decision 9) - the like (the heart, or a double press on the\n * photo), who posted it and when, its event and tags - each opens the gallery narrowed to it. Its owner changes or\n * deletes it here; a moderator hides it here, with the reason, or shows it again. Where to go next is the popup's result\n * - a popup closes by going back in the history, so a page opened before it is gone would be gone with it.\n */\nimport '@material/web/button/filled-button.js'\nimport '@material/web/button/text-button.js'\nimport '@material/web/icon/icon.js'\nimport '@operato/popup/ox-popup-actions.js'\n\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { i18next, localize } from '@operato/i18n'\nimport { notify } from '@operato/layout'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\nimport { CommonPopupStyles, PopupBodyStyles } from '@operato/styles'\n\nimport { galleryApi, galleryChanged, type Post } from '../utils/gallery-api.js'\nimport { day, days, reasonOf, t } from '../utils/gallery-words.js'\n\n@customElement('gallery-viewer')\nexport class GalleryViewer extends localize(i18next)(LitElement) {\n static styles = [\n CommonPopupStyles,\n PopupBodyStyles,\n css`\n :host {\n height: 100%;\n }\n .body {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-medium, 8px);\n }\n .stage {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 240px;\n max-height: 62vh;\n background: var(--md-sys-color-surface-container-highest);\n border-radius: var(--border-radius, 4px);\n overflow: hidden;\n user-select: none;\n }\n .stage img {\n max-width: 100%;\n max-height: 62vh;\n object-fit: contain;\n display: block;\n }\n .stage .turn {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n display: inline-flex;\n padding: 4px;\n border: 0;\n border-radius: 50%;\n background: rgb(0 0 0 / 45%);\n color: #fff;\n cursor: pointer;\n }\n .stage .previous {\n inset-inline-start: var(--spacing-small, 4px);\n }\n .stage .next {\n inset-inline-end: var(--spacing-small, 4px);\n }\n .stage .large {\n position: absolute;\n top: var(--spacing-small, 4px);\n inset-inline-end: var(--spacing-small, 4px);\n display: inline-flex;\n padding: 4px;\n border: 0;\n border-radius: 50%;\n background: rgb(0 0 0 / 45%);\n color: #fff;\n cursor: pointer;\n }\n .stage .index {\n position: absolute;\n bottom: var(--spacing-small, 4px);\n inset-inline-end: var(--spacing-medium, 8px);\n padding: 0 6px;\n border-radius: 999px;\n background: rgb(0 0 0 / 45%);\n color: #fff;\n font-size: var(--ui-t-small, 12px);\n }\n .burst {\n position: absolute;\n --md-icon-size: 72px;\n color: #fff;\n opacity: 0.9;\n animation: burst 600ms ease-out forwards;\n pointer-events: none;\n }\n @keyframes burst {\n from {\n transform: scale(0.6);\n opacity: 0.9;\n }\n to {\n transform: scale(1.3);\n opacity: 0;\n }\n }\n .line {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n font-size: var(--ui-t-small, 12px);\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n .heart {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 0;\n border: 0;\n background: none;\n color: var(--md-sys-color-on-surface);\n font: inherit;\n font-size: var(--ui-t-body, 14px);\n cursor: pointer;\n }\n /* The app's icons are drawn filled; an empty heart says not liked yet. */\n .heart md-icon {\n --md-icon-size: 22px;\n font-variation-settings: 'FILL' 0;\n }\n .heart[aria-pressed='true'] md-icon {\n color: var(--md-sys-color-error);\n font-variation-settings: 'FILL' 1;\n }\n .link {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n padding: 0;\n border: 0;\n background: none;\n color: var(--md-sys-color-primary);\n font: inherit;\n cursor: pointer;\n }\n .link:hover {\n text-decoration: underline;\n }\n .link md-icon {\n --md-icon-size: 14px;\n }\n .caption {\n margin: 0;\n font-size: var(--ui-t-body, 14px);\n line-height: 1.6;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n color: var(--md-sys-color-on-surface);\n }\n .hidden {\n padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n border-radius: var(--border-radius, 4px);\n background: var(--md-sys-color-error-container);\n color: var(--md-sys-color-on-error-container);\n font-size: var(--ui-t-small, 12px);\n }\n .likers {\n font-size: var(--ui-t-small, 12px);\n color: var(--ui-muted, var(--md-sys-color-on-surface-variant));\n }\n textarea {\n box-sizing: border-box;\n width: 100%;\n min-height: 56px;\n font: inherit;\n padding: var(--spacing-small, 4px) var(--spacing-medium, 8px);\n border: 1px solid var(--ui-line, var(--md-sys-color-outline-variant));\n border-radius: var(--border-radius, 4px);\n background: var(--md-sys-color-surface);\n color: var(--md-sys-color-on-surface);\n }\n .spacer {\n margin-inline-end: auto;\n }\n `\n ]\n\n @property({ attribute: false }) post!: Post\n\n @state() private index = 0\n @state() private likers?: { id: string; name?: string }[]\n @state() private hiding = false\n @state() private reason = ''\n @state() private burst = 0\n @state() private busy = false\n\n render() {\n const post = this.post\n if (!post) return nothing\n const photo = post.photos[this.index]\n const many = post.photos.length > 1\n return html`<div class=\"body\">\n ${post.hiddenAt ? html`<div class=\"hidden\">${t('gallery.text.hidden-note')}${post.hiddenReason ? ` · ${post.hiddenReason}` : ''}</div>` : nothing}\n <div class=\"stage\" @dblclick=${() => this.like(true, true)}>\n ${photo ? html`<img src=${photo.fullpath} alt=${post.caption ?? ''} />` : nothing}\n ${photo ? html`<button class=\"large\" aria-label=${t('gallery.button.large')} title=${t('gallery.button.large')} @click=${() => this.close({ show: { postId: post.id, index: this.index } })}><md-icon>fullscreen</md-icon></button>` : nothing}\n ${this.burst ? html`<md-icon class=\"burst\" style=\"font-variation-settings:'FILL' 1\">favorite</md-icon>` : nothing}\n ${\n many\n ? html`${this.index > 0 ? html`<button class=\"turn previous\" aria-label=${t('gallery.button.previous')} @click=${() => (this.index -= 1)}><md-icon>chevron_left</md-icon></button>` : nothing}\n ${this.index < post.photos.length - 1 ? html`<button class=\"turn next\" aria-label=${t('gallery.button.next')} @click=${() => (this.index += 1)}><md-icon>chevron_right</md-icon></button>` : nothing}\n <span class=\"index\">${this.index + 1} / ${post.photos.length}</span>`\n : nothing\n }\n </div>\n\n <div class=\"line\">\n <button\n class=\"heart\"\n aria-pressed=${String(post.liked)}\n aria-label=${t('gallery.button.like')}\n ?disabled=${this.busy}\n @click=${() => this.like(!post.liked)}\n >\n <md-icon>favorite</md-icon>\n </button>\n <button class=\"link\" ?disabled=${!post.likeCount} @click=${() => this.showLikers()}>\n ${t('gallery.text.like-count', { count: post.likeCount })}\n </button>\n <span class=\"spacer\"></span>\n <button class=\"link\" @click=${() => this.go(`gallery-page?author=${post.creator?.id}`)}>\n ${post.creator?.name ?? ''}\n </button>\n <span>${day(post.takenAt)}</span>\n </div>\n ${this.likers ? html`<div class=\"likers\">${this.likers.map(one => one.name).join(', ')}</div>` : nothing}\n ${post.caption ? html`<p class=\"caption\">${post.caption}</p>` : nothing}\n\n <div class=\"line\">\n ${\n post.event\n ? html`<button class=\"link\" @click=${() => this.go(`gallery-page?event=${post.event!.id}`)}>\n <md-icon>event</md-icon>${post.event.name} · ${days(post.event.startAt, post.event.endAt)}\n </button>`\n : nothing\n }\n ${(post.tags ?? []).map(tag => html`<button class=\"link\" @click=${() => this.go(`gallery-page?tag=${encodeURIComponent(tag)}`)}>#${tag}</button>`)}\n ${post.space === 'PERSONAL' ? html`<span>${t('gallery.space.PERSONAL')}${post.shared ? '' : ` · ${t('gallery.text.only-me')}`}</span>` : nothing}\n </div>\n\n ${\n this.hiding\n ? html`<div>\n <textarea\n maxlength=\"200\"\n placeholder=${t('gallery.text.hide-reason')}\n .value=${this.reason}\n @input=${(e: any) => (this.reason = e.target.value)}\n ></textarea>\n </div>`\n : nothing\n }\n </div>\n <ox-popup-actions>\n ${\n post.editable\n ? html`<md-text-button ?disabled=${this.busy} @click=${() => this.edit()}\n >${t('gallery.button.edit')}</md-text-button\n >\n <md-text-button ?disabled=${this.busy} @click=${() => this.deletePost()}\n >${t('gallery.button.delete')}</md-text-button\n >`\n : nothing\n }\n ${\n post.moderatable && !this.hiding\n ? post.hiddenAt\n ? html`<md-text-button ?disabled=${this.busy} @click=${() => this.unhide()}\n >${t('gallery.button.unhide')}</md-text-button\n >`\n : html`<md-text-button ?disabled=${this.busy} @click=${() => (this.hiding = true)}\n >${t('gallery.button.hide')}</md-text-button\n >`\n : nothing\n }\n ${\n this.hiding\n ? html`<md-text-button slot=\"cancel\" @click=${() => (this.hiding = false)}\n >${t('gallery.button.cancel')}</md-text-button\n >\n <md-filled-button\n slot=\"confirm\"\n ?disabled=${this.busy || !this.reason.trim()}\n @click=${() => this.hide()}\n >${t('gallery.button.hide')}</md-filled-button\n >`\n : html`<md-filled-button slot=\"confirm\" @click=${() => this.close()}\n >${t('gallery.button.close')}</md-filled-button\n >`\n }\n </ox-popup-actions>`\n }\n\n private replace(post: Post) {\n this.post = post\n this.index = Math.min(this.index, Math.max(0, post.photos.length - 1))\n galleryChanged()\n }\n\n /** Likes it, or takes the like back. A double press on the photo only likes - it never takes one back. */\n private async like(like: boolean, fromPhoto = false) {\n const post = this.post\n if (fromPhoto) {\n this.burst++\n setTimeout(() => (this.burst = 0), 600)\n if (post.liked) return\n }\n this.busy = true\n try {\n const state = await galleryApi.like(post.id, like)\n this.post = { ...post, likeCount: state.likeCount, liked: state.liked }\n if (this.likers) this.likers = await galleryApi.likers(post.id)\n this.dispatchEvent(new CustomEvent('gallery-liked', { detail: this.post, bubbles: true, composed: true }))\n } catch (error) {\n notify({ level: 'error', message: reasonOf(error) })\n } finally {\n this.busy = false\n }\n }\n\n private async showLikers() {\n if (this.likers) {\n this.likers = undefined\n return\n }\n try {\n this.likers = await galleryApi.likers(this.post.id)\n } catch (error) {\n notify({ level: 'error', message: reasonOf(error) })\n }\n }\n\n private edit() {\n this.close({ edit: this.post })\n }\n\n private async deletePost() {\n const sure = await OxPrompt.open({\n title: t('gallery.button.delete'),\n text: t('gallery.text.delete-confirm'),\n confirmButton: { text: t('gallery.button.delete') },\n cancelButton: { text: t('gallery.button.cancel') }\n })\n if (!sure) return\n this.busy = true\n try {\n await galleryApi.remove(this.post.id)\n notify({ message: t('gallery.text.deleted') })\n galleryChanged()\n this.close()\n } catch (error) {\n notify({ level: 'error', message: reasonOf(error) })\n } finally {\n this.busy = false\n }\n }\n\n private async hide() {\n this.busy = true\n try {\n const own = this.post.editable\n this.replace(await galleryApi.hide(this.post.id, this.reason.trim()))\n this.hiding = false\n this.reason = ''\n /* Its owner is told - unless the one hiding it is its owner. */\n notify({ message: own ? t('gallery.text.hidden-own') : t('gallery.text.hidden-done') })\n } catch (error) {\n notify({ level: 'error', message: reasonOf(error) })\n } finally {\n this.busy = false\n }\n }\n\n private async unhide() {\n this.busy = true\n try {\n this.replace(await galleryApi.unhide(this.post.id))\n } catch (error) {\n notify({ level: 'error', message: reasonOf(error) })\n } finally {\n this.busy = false\n }\n }\n\n private go(address: string) {\n this.close({ go: address })\n }\n\n /** The next step - a page to go to, the post to change, or the photo to see large - goes as the popup's result: the page takes it once the popup is gone. */\n private close(next?: { go?: string; edit?: Post; show?: { postId: string; index: number } }) {\n this.dispatchEvent(new CustomEvent('done', { detail: next, bubbles: true, composed: true }))\n }\n}\n"]}
@@ -1 +0,0 @@
1
- export { generateGalleryBadge, refreshGalleryBadge } from './utils/gallery-badge.js';
@@ -1,2 +0,0 @@
1
- export { generateGalleryBadge, refreshGalleryBadge } from './utils/gallery-badge.js';
2
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA","sourcesContent":["export { generateGalleryBadge, refreshGalleryBadge } from './utils/gallery-badge.js'\n"]}