Skip to content

Commit

Permalink
Add placeholders for author description, work description/synopsis, …
Browse files Browse the repository at this point in the history
…and work chapters
  • Loading branch information
ChiriVulpes committed Dec 5, 2024
1 parent c9e5221 commit 165da1c
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 20 deletions.
5 changes: 5 additions & 0 deletions lang/en-nz.quilt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ popover/account: Account Settings

# work
chapters/label=shared/term/chapters
description/empty: This work has no description.

# author
description/empty: This author prefers to remain elusive and mysterious...

# view
container/alt: main content
Expand Down Expand Up @@ -199,6 +203,7 @@ action/delete: Delete Work

### chapters
title=shared/term/chapters
content/empty: This work does not contain any chapters.
action/label/new: New Chapter
action/label/view=shared/action/view
action/label/love=shared/action/love
Expand Down
8 changes: 7 additions & 1 deletion src/ui/component/Author.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { AuthorFull } from "api.fluff4.me"
import Component from "ui/Component"
import Block from "ui/component/core/Block"
import Slot from "ui/component/core/Slot"

export default Component.Builder((component, author: AuthorFull) => {
component
Expand All @@ -17,7 +18,12 @@ export default Component.Builder((component, author: AuthorFull) => {

Component()
.style("author-description")
.setMarkdownContent(author.description.body)
.append(Slot.using(author.description.body, (slot, body) => {
if (body)
slot.setMarkdownContent(body)
else
slot.style("placeholder").text.use("author/description/empty")
}))
.appendTo(block.content)

return block
Expand Down
41 changes: 36 additions & 5 deletions src/ui/component/Work.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { Author, Work as WorkData } from "api.fluff4.me"
import type { Author, Work as WorkData, WorkFull } from "api.fluff4.me"
import Session from "model/Session"
import Tags from "model/Tags"
import Component from "ui/Component"
import Block from "ui/component/core/Block"
import Button from "ui/component/core/Button"
import Link from "ui/component/core/Link"
import Slot from "ui/component/core/Slot"
import TextLabel from "ui/component/core/TextLabel"
import Timestamp from "ui/component/core/Timestamp"
import Tag from "ui/component/Tag"
Expand All @@ -15,7 +16,9 @@ interface WorkExtensions {

interface Work extends Block, WorkExtensions { }

const Work = Component.Builder(async (component, work: WorkData, author?: Author): Promise<Work> => {
const Work = Component.Builder(async (component, work: WorkData & Partial<WorkFull>, author?: Author): Promise<Work> => {
author = author ?? work.synopsis?.mentions[0]

component
.viewTransition("work")
.style("work")
Expand All @@ -38,11 +41,39 @@ const Work = Component.Builder(async (component, work: WorkData, author?: Author
.text.set(author.name))

block.content.style("work-content")
Component()
.style("work-description")
.setMarkdownContent(work.description)

Slot()
.use(isFlush, (slot, isFlush) => {
const shouldShowDescription = isFlush || (work.synopsis?.body && work.description)
if (shouldShowDescription)
Component()
.style("work-description")
.style.toggle(!work.description, "placeholder")
.tweak(component => {
if (work.description)
component.text.set(work.description)
else
component.text.use("work/description/empty")
})
.appendTo(slot)

if (!isFlush)
Component()
.style("work-synopsis")
.style.toggle(!work.synopsis?.body && !work.description, "placeholder")
.append(Slot.using(work.synopsis ?? work.description, (slot, synopsis) => {
if (typeof synopsis === "string")
slot.text.set(synopsis)
else if (!synopsis.body)
slot.text.use("work/description/empty")
else
slot.setMarkdownContent(synopsis.body)
}))
.appendTo(slot)
})
.appendTo(block.content)


let tagsWrapper: Component | undefined
const tags = await Tags.resolve(work.global_tags)
for (const tag of tags) {
Expand Down
16 changes: 3 additions & 13 deletions src/ui/component/core/Slot.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Component from "ui/Component"
import type State from "utility/State"
import type { UnsubscribeState } from "utility/State"
import State from "utility/State"

export type SlotCleanup = () => any

Expand Down Expand Up @@ -63,18 +63,8 @@ const Slot = Object.assign(
.event.subscribe("remove", () => cleanup?.())
}),
{
// Using: Component.Builder(<T> (slot: Component, state: State<T>, contentSupplier: (value: T) => Component | undefined): Slot => {
// return slot.and(Slot)
// .use(state, (slot, value) => {
// contentSupplier(value)?.appendTo(slot)
// })
// }),
// If: Component.Builder((slot: Component, state: State<boolean>, contentSupplier: () => Component | undefined): Slot => {
// return slot.and(Slot)
// .if(state, (slot) => {
// contentSupplier()?.appendTo(slot)
// })
// }),
using: <T> (value: T | State<T>, initialiser: (slot: Slot, value: T) => SlotCleanup | Component | void) =>
Slot().use(State.get(value), initialiser),
}
)

Expand Down
5 changes: 5 additions & 0 deletions src/ui/view/WorkView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import EndpointChapterGetAll from "endpoint/chapter/EndpointChapterGetAll"
import type { WorkParams } from "endpoint/work/EndpointWorkGet"
import EndpointWorkGet from "endpoint/work/EndpointWorkGet"
import Session from "model/Session"
import Component from "ui/Component"
import Chapter from "ui/component/Chapter"
import Button from "ui/component/core/Button"
import Paginator from "ui/component/core/Paginator"
Expand Down Expand Up @@ -51,6 +52,10 @@ export default ViewDefinition({
Chapter(chapterData, workData, authorData)
.appendTo(slot)
})
paginator.orElse(slot => Component()
.style("placeholder")
.text.use("view/work/chapters/content/empty")
.appendTo(slot))

return view
},
Expand Down
4 changes: 3 additions & 1 deletion src/ui/view/work/WorkEditForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default Component.Builder((component, state: State<WorkFull | undefined>)
.content((content, label) => content.append(vanityInput.setLabel(label)))

const descriptionInput = Textarea()
.default.bind(state.map(component, work => work?.description))
table.label(label => label.text.use("view/work-edit/shared/form/description/label"))
.content((content, label) => content.append(descriptionInput.setLabel(label)))

Expand Down Expand Up @@ -82,7 +83,8 @@ export default Component.Builder((component, state: State<WorkFull | undefined>)
body: {
name: nameInput.value,
vanity: vanityInput.value,
description: synopsisInput.useMarkdown(),
description: descriptionInput.value,
synopsis: synopsisInput.useMarkdown(),
},
})
}
Expand Down
10 changes: 10 additions & 0 deletions src/utility/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type StateOr<T> = State<T> | T
export type UnsubscribeState = () => void

interface ReadableState<T, E = T> {
readonly isState: true
readonly value: T

readonly equals: <V extends T>(value: V) => boolean
Expand Down Expand Up @@ -49,6 +50,7 @@ interface InternalState<T> {

function State<T> (defaultValue: T, equals?: (a: T, b: T) => boolean): State<T> {
const result: Mutable<State<T>> & InternalState<T> = {
isState: true,
[SYMBOL_VALUE]: defaultValue,
[SYMBOL_SUBSCRIBERS]: [],
get value () {
Expand Down Expand Up @@ -151,6 +153,14 @@ function State<T> (defaultValue: T, equals?: (a: T, b: T) => boolean): State<T>

namespace State {

export function is<T> (value: unknown): value is ReadableState<T> {
return typeof value === "object" && (value as ReadableState<T>)?.isState === true
}

export function get<T> (value: T | State<T>): ReadableState<T> {
return is<T>(value) ? value : State(value)
}

export interface Generator<T> extends ReadableState<T> {
refresh (): this
observe (owner: Component, ...states: ReadableState<any>[]): this
Expand Down

0 comments on commit 165da1c

Please sign in to comment.