theme-change: removed in favor of built in

This commit is contained in:
Tigor Hutasuhut 2024-05-04 19:39:02 +07:00
parent 2e71aa15ca
commit d90dbb5156
9 changed files with 109 additions and 92 deletions

View file

@ -9,7 +9,6 @@ export GOOSE_MIGRATION_DIR=db/migrations
export REDMAGE_WEB_DEPENDENCIES_HTMX_VERSION=$(shell echo "$${REDMAGE_WEB_DEPENDENCIES_HTMX_VERSION:-1.9.12}") export REDMAGE_WEB_DEPENDENCIES_HTMX_VERSION=$(shell echo "$${REDMAGE_WEB_DEPENDENCIES_HTMX_VERSION:-1.9.12}")
export REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION=$(shell echo "$${REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION:-1.11.10}") export REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION=$(shell echo "$${REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION:-1.11.10}")
export REDMAGE_WEB_DEPENDENCIES_THEMECHANGE_VERSION=$(shell echo "$${REDMAGE_WEB_DEPENDENCIES_THEMECHANGE_VERSION:-2.0.2}")
start: dev-dependencies start: dev-dependencies
@tailwindcss -i views/style.css -o public/style.css --watch & @tailwindcss -i views/style.css -o public/style.css --watch &
@ -63,11 +62,6 @@ build-dependencies:
echo "Dayjs Timezone ${REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION} plugin not found, installing it" echo "Dayjs Timezone ${REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION} plugin not found, installing it"
curl -o public/dayjs-timezone-${REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION}.min.js https://cdnjs.cloudflare.com/ajax/libs/dayjs/${REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION}/plugin/timezone.min.js curl -o public/dayjs-timezone-${REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION}.min.js https://cdnjs.cloudflare.com/ajax/libs/dayjs/${REDMAGE_WEB_DEPENDENCIES_DAYJS_VERSION}/plugin/timezone.min.js
fi fi
@if [ ! -f "public/theme-change-${REDMAGE_WEB_DEPENDENCIES_THEMECHANGE_VERSION}.min.js" ]; then
mkdir -p public
echo "Theme change ${REDMAGE_WEB_DEPENDENCIES_THEMECHANGE_VERSION} not found, installing it"
curl -o public/theme-change-${REDMAGE_WEB_DEPENDENCIES_THEMECHANGE_VERSION}.min.js https://cdn.jsdelivr.net/npm/theme-change@${REDMAGE_WEB_DEPENDENCIES_THEMECHANGE_VERSION}/index.js
fi
build: build-dependencies prepare build: build-dependencies prepare
go build -o redmage go build -o redmage

View file

@ -31,8 +31,7 @@ type API struct {
config *config.Config config *config.Config
imageSemaphore chan struct{} imageSemaphore chan struct{}
subredditSemaphore chan struct{}
reddit *reddit.Reddit reddit *reddit.Reddit
@ -56,17 +55,16 @@ func New(deps Dependencies) *API {
panic(err) panic(err)
} }
api := &API{ api := &API{
db: bob.New(deps.DB), db: bob.New(deps.DB),
sqldb: deps.DB, sqldb: deps.DB,
scheduler: cron.New(), scheduler: cron.New(),
scheduleMap: make(map[cron.EntryID]*models.Subreddit, 8), scheduleMap: make(map[cron.EntryID]*models.Subreddit, 8),
downloadBroadcast: broadcast.NewRelay[bmessage.ImageDownloadMessage](), downloadBroadcast: broadcast.NewRelay[bmessage.ImageDownloadMessage](),
config: deps.Config, config: deps.Config,
imageSemaphore: make(chan struct{}, deps.Config.Int("download.concurrency.images")), imageSemaphore: make(chan struct{}, deps.Config.Int("download.concurrency.images")),
subredditSemaphore: make(chan struct{}, deps.Config.Int("download.concurrency.subreddits")), reddit: deps.Reddit,
reddit: deps.Reddit, subscriber: deps.Subscriber,
subscriber: deps.Subscriber, publisher: deps.Publisher,
publisher: deps.Publisher,
} }
if err := api.StartScheduler(context.Background()); err != nil { if err := api.StartScheduler(context.Background()); err != nil {

View file

@ -56,9 +56,8 @@ var DefaultConfig = map[string]any{
"telemetry.trace.ratio": 1, "telemetry.trace.ratio": 1,
"web.dependencies.htmx.version": "1.9.12", "web.dependencies.htmx.version": "1.9.12",
"web.dependencies.dayjs.version": "1.11.10", "web.dependencies.dayjs.version": "1.11.10",
"web.dependencies.themechange.version": "2.0.2",
"runtime.version": "0.0.1", "runtime.version": "0.0.1",
"runtime.environment": "development", "runtime.environment": "development",

View file

@ -2,7 +2,7 @@ package components
templ Doctype() { templ Doctype() {
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en" data-theme="dark">
{ children... } { children... }
</html> </html>
} }

View file

@ -4,13 +4,15 @@ import "github.com/tigorlazuardi/redmage/views"
templ Head(vc *views.Context, extras ...templ.Component) { templ Head(vc *views.Context, extras ...templ.Component) {
<head> <head>
<script>
document.querySelector('html').dataset.theme = localStorage.getItem('theme') || '';
</script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="keywords" content="Reddit, Image, Downloader"/> <meta name="keywords" content="Reddit, Image, Downloader"/>
<link rel="stylesheet" href="/public/style.css"/> <link rel="stylesheet" href="/public/style.css"/>
<link rel="icon" href="/public/favicon.svg"/> <link rel="icon" href="/public/favicon.svg"/>
@Dayjs(vc) @Dayjs(vc)
@HTMX(vc) @HTMX(vc)
@ThemeChange(vc)
if vc.Config.Bool("http.hotreload") { if vc.Config.Bool("http.hotreload") {
<script src="/public/hot_reload.js"></script> <script src="/public/hot_reload.js"></script>
} }

View file

@ -86,7 +86,9 @@ templ Navbar(c *views.Context) {
templ navList(c *views.Context) { templ navList(c *views.Context) {
@createLink(c, "/", "Home", true) @createLink(c, "/", "Home", true)
@createLink(c, "/config", "Config", false) @createLink(c, "/config", "Config", false)
@createLink(c, "/devices", "Devices", true)
@createLink(c, "/subreddits", "Subreddits", true) @createLink(c, "/subreddits", "Subreddits", true)
@createLink(c, "/schedules", "Schedules", true)
<div class="flex-1 flex-shrink-0"></div> <div class="flex-1 flex-shrink-0"></div>
<div class="divider"></div> <div class="divider"></div>
@createLink(c, "/about", "About", true) @createLink(c, "/about", "About", true)
@ -95,7 +97,7 @@ templ navList(c *views.Context) {
templ createLink(c *views.Context, path string, text string, boost bool) { templ createLink(c *views.Context, path string, text string, boost bool) {
<a <a
href={ templ.SafeURL(path) } href={ templ.URL(path) }
class={ utils.CX(map[string]bool{ class={ utils.CX(map[string]bool{
"hover:bg-accent": true, "hover:bg-accent": true,
"hover:text-neutral-50": true, "hover:text-neutral-50": true,

View file

@ -1,8 +0,0 @@
package components
import "github.com/tigorlazuardi/redmage/views"
import "fmt"
templ ThemeChange(c *views.Context) {
<script src={ fmt.Sprintf("/public/theme-change-%s.min.js", c.Config.String("web.dependencies.themechange.version")) }></script>
}

View file

@ -17,26 +17,44 @@ templ ConfigContent(c *views.Context) {
@components.Container() { @components.Container() {
<h1>Config</h1> <h1>Config</h1>
<div class="divider"></div> <div class="divider"></div>
<div class="grid grid-cols-2 items-center"> <h2>Theme</h2>
<h2>Theme</h2> @SelectThemeInput()
@SelectThemeInput()
</div>
} }
</main> </main>
} }
templ SelectThemeInput() { templ SelectThemeInput() {
<select class="select select-ghost select-bordered w-full" data-choose-theme> <div
<option value="light">Light (Default)</option> class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 gap-4"
<option value="dark">Dark</option> onchange="document.querySelector('html').dataset.theme = event.target.value; localStorage.setItem('theme', event.target.value)"
<option value="cupcake">Cupcake</option> >
<option value="bumblebee">Bumblebee</option> @themeRadio("default", "System (Default)")
<option value="emerald">Emerald</option> @themeRadio("light", "Light")
<option value="corporate">Corporate</option> @themeRadio("dark", "Dark")
<option value="synthwave">Synthwave</option> @themeRadio("aqua", "Aqua")
<option value="retru">Retro</option> @themeRadio("bumblebee", "Bumblebee")
<option value="cyberpunk">Cyberpunk</option> @themeRadio("corporate", "Corporate")
<option value="valentine">Valentine</option> @themeRadio("cupcake", "Cupcake")
<option value="halloween">Halloween</option> @themeRadio("cyberpunk", "Cyberpunk")
</select> @themeRadio("emerald", "Emerald")
@themeRadio("halloween", "Halloween")
@themeRadio("retro", "Retro")
@themeRadio("synthwave", "Synthwave")
@themeRadio("valentine", "Valentine")
</div>
<script>
{
const theme = localStorage.getItem('theme') || 'default';
document.querySelector(`input[name="theme-radios"][value="${theme}"]`).checked = true
}
</script>
}
templ themeRadio(value, display string) {
<div class="form-control">
<label class="label cursor-pointer gap-4 justify-start">
<input type="radio" name="theme-radios" class="radio theme-controller" value={ value }/>
<span class="label-text">{ display }</span>
</label>
</div>
} }

View file

@ -28,22 +28,9 @@ templ HomeContent(c *views.Context, data Data) {
@components.ErrorToast(data.Error) @components.ErrorToast(data.Error)
} else { } else {
<section class="mb-4 mx-auto"> <section class="mb-4 mx-auto">
<div <h1 class="mb-4">
class="flex flex-wrap content-center gap-x-8" Recently Added
hx-get="/" </h1>
hx-target="#recently-added-images"
hx-select="#recently-added-images"
hx-swap="outerHTML"
hx-trigger="change"
hx-include="this"
hx-push-url="true"
>
<h1 class="mb-4">
Recently Added
</h1>
@recentRangeInput(c)
@nsfwToggle(c, data)
</div>
<div id="recently-added-images"> <div id="recently-added-images">
if data.TotalImages == 0 { if data.TotalImages == 0 {
<h2 class="mt-4">There are no recently added images in the current time range.</h2> <h2 class="mt-4">There are no recently added images in the current time range.</h2>
@ -52,6 +39,20 @@ templ HomeContent(c *views.Context, data Data) {
{ strconv.FormatInt(data.TotalImages, 10) } Images { strconv.FormatInt(data.TotalImages, 10) } Images
</h2> </h2>
} }
<div
id="filter-bar"
hx-get="/"
hx-target="#recently-added-images"
hx-select="#recently-added-images"
hx-swap="outerHTML"
hx-trigger="change"
hx-include="this"
hx-push-url="true"
class="flex flex-wrap content-center gap-x-8"
>
@recentRangeInput(c)
@nsfwToggle(c, data)
</div>
for _, recently := range data.RecentlyAddedImages { for _, recently := range data.RecentlyAddedImages {
<div class="divider"></div> <div class="divider"></div>
<h2 class="mt-4">{ recently.Device.Name }</h2> <h2 class="mt-4">{ recently.Device.Name }</h2>
@ -82,19 +83,25 @@ templ HomeContent(c *views.Context, data Data) {
} }
templ recentRangeInput(c *views.Context) { templ recentRangeInput(c *views.Context) {
<select <div class="form-control">
name="created_at" <label class="label gap-4">
class="select select-ghost select-bordered" <span class="label-text">Range</span>
> <select
@recentlyRangeOption(c, "-10800", "3 Hours") id="select-range"
@recentlyRangeOption(c, "-21600", "6 Hours") name="created_at"
@recentlyRangeOption(c, "-43200", "12 Hours") class="select select-ghost select-bordered"
@recentlyRangeOption(c, "-86400", "1 Day") >
@recentlyRangeOption(c, "-172800", "2 Days") @recentlyRangeOption(c, "-10800", "3 Hours")
@recentlyRangeOption(c, "-259200", "3 Days") @recentlyRangeOption(c, "-21600", "6 Hours")
@recentlyRangeOption(c, "-604800", "7 Days") @recentlyRangeOption(c, "-43200", "12 Hours")
@recentlyRangeOption(c, "-2592000", "30 Days") @recentlyRangeOption(c, "-86400", "1 Day")
</select> @recentlyRangeOption(c, "-172800", "2 Days")
@recentlyRangeOption(c, "-259200", "3 Days")
@recentlyRangeOption(c, "-604800", "7 Days")
@recentlyRangeOption(c, "-2592000", "30 Days")
</select>
</label>
</div>
} }
templ recentlyRangeOption(c *views.Context, value, text string) { templ recentlyRangeOption(c *views.Context, value, text string) {
@ -108,22 +115,27 @@ templ recentlyRangeOption(c *views.Context, value, text string) {
} }
templ nsfwToggle(c *views.Context, data Data) { templ nsfwToggle(c *views.Context, data Data) {
<select <div class="form-control">
name="sfw" <label class="label gap-4">
class="select select-ghost select-bordered" <span class="label-text">NSFW</span>
> <select
if (c.Request.URL.Query().Get("sfw") == "1") || data.SFW { name="sfw"
<option value="0">NSFW - Show</option> class="select select-ghost select-bordered"
<option selected="selected" value="1">NSFW - Hide</option> >
} else { if (c.Request.URL.Query().Get("sfw") == "1") || data.SFW {
<option selected="selected" value="0">NSFW - Show</option> <option value="0">Show</option>
<option value="1">NSFW - Hide</option> <option selected="selected" value="1">Hide</option>
} } else {
</select> <option selected="selected" value="0">Show</option>
<option value="1">Hide</option>
}
</select>
</label>
</div>
} }
templ RecentlyAddedImageList(images models.ImageSlice, opts components.ImageCardOption) { templ RecentlyAddedImageList(images models.ImageSlice, opts components.ImageCardOption) {
<div class="overflow-x-auto flex gap-4 p-6 shadow-inner bg-base-300 rounded-2xl w-[85vw] md:w-full scrollbar-track-base-100 scrollbar-thumb-base-200 scrollbar-thin"> <div class="overflow-x-auto flex gap-4 p-6 shadow-inner bg-base-300 rounded-2xl w-[85vw] md:w-full scrollbar-track-base-100 scrollbar-thumb-primary scrollbar-thin hover:scrollbar-thumb-base-300">
for _, data := range images { for _, data := range images {
@components.ImageCard(data, 0) @components.ImageCard(data, 0)
} }