2024-05-02 15:42:10 +07:00
|
|
|
package components
|
2024-04-27 22:07:20 +07:00
|
|
|
|
|
|
|
import "github.com/tigorlazuardi/redmage/models"
|
|
|
|
import "fmt"
|
2024-05-08 19:32:14 +07:00
|
|
|
import "time"
|
2024-04-27 22:07:20 +07:00
|
|
|
|
|
|
|
type ImageCardOption uint
|
|
|
|
|
|
|
|
func (o ImageCardOption) Has(opt ImageCardOption) bool {
|
|
|
|
return o&opt != 0
|
|
|
|
}
|
|
|
|
|
2024-05-08 09:22:16 +07:00
|
|
|
func (o ImageCardOption) SetCond(opt ImageCardOption, cond bool) ImageCardOption {
|
|
|
|
if cond {
|
|
|
|
return o | opt
|
|
|
|
}
|
|
|
|
return o
|
|
|
|
}
|
|
|
|
|
2024-04-27 22:07:20 +07:00
|
|
|
const (
|
2024-05-08 09:22:16 +07:00
|
|
|
HideNothing ImageCardOption = 0
|
|
|
|
HideTitle ImageCardOption = 1 << iota
|
2024-04-27 22:07:20 +07:00
|
|
|
HideSubreddit
|
|
|
|
HidePoster
|
2024-05-07 22:50:23 +07:00
|
|
|
HideDevice
|
2024-04-27 22:07:20 +07:00
|
|
|
)
|
|
|
|
|
2024-05-02 15:42:10 +07:00
|
|
|
templ ImageCard(data *models.Image, opts ImageCardOption) {
|
2024-05-08 19:32:14 +07:00
|
|
|
<div
|
|
|
|
x-data={ fmt.Sprintf(`{
|
|
|
|
time: %d,
|
|
|
|
get timeTooltip() {
|
|
|
|
return dayjs.unix(this.time).tz(dayjs.tz.guess()).format('ddd, D MMM YYYY HH:mm:ss Z')
|
|
|
|
},
|
|
|
|
get relativeTime() {
|
|
|
|
return dayjs.unix(this.time).tz(dayjs.tz.guess()).fromNow()
|
|
|
|
},
|
|
|
|
}`, data.CreatedAt) }
|
|
|
|
class="not-prose card card-bordered bg-base-100 hover:bg-base-200 shadow-xl min-w-[16rem] max-w-[16rem] rounded-xl top-0 hover:-top-1 hover:drop-shadow-2xl transition-all"
|
2024-06-10 14:52:53 +07:00
|
|
|
id={ fmt.Sprintf("image-card-%s-%s", data.Subreddit, data.PostName) }
|
2024-05-08 19:32:14 +07:00
|
|
|
>
|
2024-04-27 22:07:20 +07:00
|
|
|
<figure>
|
|
|
|
<a
|
|
|
|
href={ templ.URL(fmt.Sprintf("/img/%s", data.ImageRelativePath)) }
|
2024-04-29 21:45:18 +07:00
|
|
|
target="_blank"
|
2024-04-27 22:07:20 +07:00
|
|
|
>
|
|
|
|
<img
|
2024-05-01 18:16:54 +07:00
|
|
|
class="object-contain max-w-[16rem] max-h-[16rem]"
|
2024-04-27 22:07:20 +07:00
|
|
|
src={ fmt.Sprintf("/img/%s", data.ThumbnailRelativePath) }
|
2024-04-30 14:12:33 +07:00
|
|
|
alt={ data.PostTitle }
|
2024-05-05 23:28:29 +07:00
|
|
|
loading="lazy"
|
2024-04-27 22:07:20 +07:00
|
|
|
/>
|
|
|
|
</a>
|
|
|
|
</figure>
|
2024-05-01 14:39:34 +07:00
|
|
|
<div class="flex-1"></div>
|
2024-04-27 22:07:20 +07:00
|
|
|
<div class="card-body">
|
|
|
|
if !opts.Has(HideTitle) {
|
|
|
|
<a
|
|
|
|
href={ templ.URL(data.PostURL) }
|
2024-05-01 14:39:34 +07:00
|
|
|
class="card-title font-bold underline text-sm text-primary"
|
2024-04-30 14:12:33 +07:00
|
|
|
>{ truncateTitle(data.PostTitle) }</a>
|
2024-04-27 22:07:20 +07:00
|
|
|
}
|
2024-05-01 14:39:34 +07:00
|
|
|
<a class="text-primary text-sm underline" href={ templ.URL(data.PostAuthorURL) }>{ data.PostAuthor }</a>
|
2024-05-01 00:02:30 +07:00
|
|
|
<div class="flex-1"></div>
|
2024-05-01 14:39:34 +07:00
|
|
|
<div class="flex">
|
2024-05-08 19:32:14 +07:00
|
|
|
<div class="tooltip" :data-tip="timeTooltip">
|
|
|
|
<span class="text-xs" :class="{ 'text-xs': false }" x-text="relativeTime">{ time.Unix(data.CreatedAt, 0).Format("Mon, _2 Jan 2006 15:04:05 MST") } </span>
|
|
|
|
</div>
|
2024-04-28 22:00:56 +07:00
|
|
|
</div>
|
2024-05-01 14:27:09 +07:00
|
|
|
<div class="grid grid-cols-2">
|
|
|
|
<p class="text-xs">{ fmt.Sprintf("%d \u00d7 %d", data.ImageWidth, data.ImageHeight) } px</p>
|
|
|
|
<p class="text-xs text-end">{ formatByteSize(data.ImageSize) }</p>
|
2024-04-28 10:25:09 +07:00
|
|
|
</div>
|
2024-05-07 22:50:23 +07:00
|
|
|
if data.R.Device != nil && !opts.Has(HideDevice) {
|
2024-05-12 22:45:41 +07:00
|
|
|
<a class="my-4" href={ templ.URL(fmt.Sprintf("/devices/details/%s", data.R.Device.Slug)) }>
|
|
|
|
<div class="divider text-accent underline text-wrap text-center">{ data.R.Device.Name }</div>
|
2024-05-07 22:50:23 +07:00
|
|
|
</a>
|
|
|
|
}
|
2024-04-27 22:07:20 +07:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
}
|
2024-04-28 10:25:09 +07:00
|
|
|
|
2024-05-01 14:27:09 +07:00
|
|
|
func formatByteSize(size int64) string {
|
|
|
|
if size < 1024 {
|
|
|
|
return fmt.Sprintf("%d B", size)
|
|
|
|
}
|
|
|
|
if size < 1024*1024 {
|
|
|
|
return fmt.Sprintf("%.2f KiB", float64(size)/1024)
|
|
|
|
}
|
|
|
|
if size < 1024*1024*1024 {
|
|
|
|
return fmt.Sprintf("%.2f MiB", float64(size)/(1024*1024))
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("%.2f GiB", float64(size)/(1024*1024*1024))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-04-30 12:54:16 +07:00
|
|
|
func truncateTitle(title string) string {
|
2024-05-02 15:42:10 +07:00
|
|
|
if len(title) > 52 {
|
2024-04-30 12:54:16 +07:00
|
|
|
return title[:50] + "..."
|
|
|
|
}
|
|
|
|
return title
|
|
|
|
}
|