This commit is contained in:
video-prize-ranch 2022-01-17 17:11:33 -05:00
parent a25b5374c1
commit 34f09c36fb
No known key found for this signature in database
GPG Key ID: D8EAA4C5B12A7281
15 changed files with 150 additions and 119 deletions

View File

@ -27,15 +27,13 @@ Features:
This is currently very early stage software. Some things left to implement (contributions welcome!): This is currently very early stage software. Some things left to implement (contributions welcome!):
- [ ] Streaming (currently media is downloaded in full in rimgu before it's returned) - [x] Streaming (currently media is downloaded in full in rimgu before it's returned)
- [ ] Localization/internationalization - [ ] Localization/internationalization
- [ ] Pretty CSS styling (responsive?) - [x] Pretty CSS styling (responsive?)
- [ ] Automatically fetch / rotate / renew client ID
- [ ] Support for other popular image sites than only imgur - [ ] Support for other popular image sites than only imgur
- [ ] Filtering and exploration on user/tags pages - [ ] Filtering and exploration on user/tags pages
- [ ] Responsive scaling of videos on user/tags pages - [ ] Responsive scaling of videos on user/tags pages
- [ ] Prometheus metrics - [x] Logo
- [ ] Logo
- [ ] SOCKS5 proxy support - [ ] SOCKS5 proxy support
Things that are *currently* considered out of scope: Things that are *currently* considered out of scope:

View File

@ -26,12 +26,19 @@ func FetchAlbum(albumID string) (types.Album, error) {
data := gjson.Parse(string(body)) data := gjson.Parse(string(body))
media := make([]string, 0) media := make([]types.Media, 0)
data.Get("media").ForEach( data.Get("media").ForEach(
func(key gjson.Result, value gjson.Result) bool { func(key gjson.Result, value gjson.Result) bool {
url := value.Get("url").String() url := value.Get("url").String()
url = strings.ReplaceAll(url, "https://i.imgur.com", "/media") url = strings.ReplaceAll(url, "https://i.imgur.com", "/media")
media = append(media, url)
media = append(media, types.Media{
Id: value.Get("id").String(),
Name: value.Get("name").String(),
Title: value.Get("metadata.title").String(),
Description: value.Get("metadata.description").String(),
Url: url,
})
return true return true
}, },
@ -46,8 +53,6 @@ func FetchAlbum(albumID string) (types.Album, error) {
Id: data.Get("id").String(), Id: data.Get("id").String(),
Title: data.Get("title").String(), Title: data.Get("title").String(),
Views: data.Get("view_count").Int(), Views: data.Get("view_count").Int(),
Upvotes: data.Get("upvote_count").Int(),
Downvotes: data.Get("downvote_count").Int(),
CreatedAt: createdAt.Format("January 2, 2006 3:04 PM"), CreatedAt: createdAt.Format("January 2, 2006 3:04 PM"),
Media: media, Media: media,
}, nil }, nil

View File

@ -43,7 +43,7 @@ func main() {
Root: http.FS(static.GetFiles()), Root: http.FS(static.GetFiles()),
})) }))
app.Get("/media/:baseName.:extension", pages.HandleMedia) app.Get("/:baseName.:extension", pages.HandleMedia)
app.Get("/a/:albumID", pages.HandleAlbum) app.Get("/a/:albumID", pages.HandleAlbum)
app.Get("/t/:tagID", pages.HandleAlbum) app.Get("/t/:tagID", pages.HandleAlbum)
/*app.Get("/user/:userID", pages.HandleUser) /*app.Get("/user/:userID", pages.HandleUser)

View File

@ -16,5 +16,6 @@ func HandleAlbum(c *fiber.Ctx) error {
return c.Render("gallery", fiber.Map{ return c.Render("gallery", fiber.Map{
"album": album, "album": album,
"isAlbum": true,
}) })
} }

View File

@ -0,0 +1,17 @@
h1 {
margin: 0;
}
img {
max-width: 100%;
}
.imageMeta__wrapper,
.imageMeta {
display: flex;
gap: 12px;
}
.imageMeta__wrapper {
gap: 2rem;
}

View File

@ -1,11 +1,39 @@
a {
text-decoration: none;
}
body { body {
background-color: black;
color: white;
font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Ubuntu, roboto, noto, arial, sans-serif; font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Ubuntu, roboto, noto, arial, sans-serif;
} }
main { nav {
margin: 0 18vw; display: flex;
align-items: center;
} }
img { .logo {
max-width: 100%; filter: invert(1) hue-rotate(180deg);
}
main {
margin: 0 24vw;
}
footer {
display: flex;
justify-content: center;
flex-direction: row;
gap: 10px;
}
@media only screen and (max-width: 812px) {
main {
margin: 0;
}
footer {
flex-direction: column;
text-align: center;
}
} }

View File

@ -0,0 +1,22 @@
/* fallback */
@font-face {
font-family: 'Material Icons Outlined';
font-style: normal;
font-weight: 400;
src: url(Material-Icons-Outlined.woff2) format('woff2');
}
.material-icons-outlined {
font-family: 'Material Icons Outlined';
font-weight: normal;
font-style: normal;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-moz-font-feature-settings: 'liga';
-moz-osx-font-smoothing: grayscale;
}

Binary file not shown.

View File

@ -8,5 +8,5 @@ type Album struct {
Downvotes int64 Downvotes int64
CreatedAt string CreatedAt string
UpdatedAt string UpdatedAt string
Media []string Media []Media
} }

9
types/Media.go Normal file
View File

@ -0,0 +1,9 @@
package types
type Media struct {
Id string
Name string
Title string
Description string
Url string
}

8
types/User.go Normal file
View File

@ -0,0 +1,8 @@
package types
type User struct {
Id string
Username string
Avatar string
CreatedAt string
}

View File

@ -3,17 +3,52 @@
<head> <head>
{{> partials/head }} {{> partials/head }}
<link rel="stylesheet" href="/static/fonts/Material-Icons-Outlined.css" />
<link rel="stylesheet" href="/static/css/album.css" /> <link rel="stylesheet" href="/static/css/album.css" />
</head> </head>
<body> <body>
{{> partials/header }} {{> partials/header }}
<main> <main>
<h1>{{album.Title}}</h1>
<div class="imageMeta__wrapper">
<div class="imageMeta">
<p><span class="material-icons-outlined" title="Views">visibility</span> {{album.Views}}</p>
{{#unless isAlbum}}
<p><span class="material-icons-outlined" title="Likes">thumb_up</span> {{album.Upvotes}}</p>
<p><span class="material-icons-outlined" title="Dislilkes">thumb_down</span> {{album.Downvotes}}</p>
{{/unless}}
</div>
<!--<div class="videoDesc__channel">
<a href="{{claim.Channel.RelUrl}}">
{{#if claim.Channel.Thumbnail}}
<img src="{{claim.Channel.Thumbnail}}&w=56&h=56" class="pfp" width="56" height="56" loading="lazy" />
{{/if}}
</a>
<a href="{{claim.Channel.RelUrl}}">
<p>
<b>{{claim.Channel.Title}}</b>
</p>
</a>
</div>-->
</div>
{{#each album.Media}} {{#each album.Media}}
<img src="{{this}}" loading="lazy"> {{#if this.Title}}
<h3>{{this.Title}}</h3>
{{/if}}
{{#if this.Description}}
<p>{{this.Description}}</p>
{{/if}}
<img src="{{this.Url}}" loading="lazy">
{{/each}} {{/each}}
</main> </main>
{{> partials/footer }}
</body> </body>
</html> </html>

View File

@ -1,103 +0,0 @@
mixin commentbox(comment)
div(class='GalleryComment')
div(class='GalleryComment-wrapper')
div(class='GalleryComment-content')
div(class='GalleryComment-byLine')
div(class='Meta')
div(class='GalleryComment-avatar-bar')
div(class='avatar')
if comment.account.username === '[deleted]'
span(title='[deleted]')
else
a(title='View profile of '+comment.account.username, href='/user/'+comment.account.username)
span(title=comment.account.username, style='background-image: url("' + util.proxyURL(comment.account.avatar) + '");')
a(class='author-name', title='View profile of '+comment.account.username, href='/user/'+comment.account.username) #{comment.account.username}
span(class="date", title=comment.created_at)
span(class="delimiter") •
span #{comment.created_at} via <span class="platform bold">#{comment.platform}</a>
div(class='GalleryComment-body')
span(class='Linkify')
| !{util.linkify(comment.comment)}
div(class='GalleryComment-actions')
div(class='vote-btn upvote actions-btn' title='Upvotes')
div(class='Vote Vote-up')
svg(width='16', height='16', viewBox='0 0 16 16', fill='none', xmlns='http://www.w3.org/2000/svg')
title Upvotes
| <path fill="none" stroke="#B4B9C2" stroke-width="2" fill-rule="evenodd" clip-rule="evenodd" d="M7.197 2.524a1.2 1.2 0 011.606 0c.521.46 1.302 1.182 2.363 2.243a29.617 29.617 0 012.423 2.722c.339.435.025 1.028-.526 1.028h-2.397v4.147c0 .524-.306.982-.823 1.064-.417.066-1.014.122-1.843.122s-1.427-.056-1.843-.122c-.517-.082-.824-.54-.824-1.064V8.517H2.937c-.552 0-.865-.593-.527-1.028.52-.669 1.32-1.62 2.423-2.722a52.996 52.996 0 012.364-2.243z"></path>
.points + #{comment.upvote_count}
div(class='vote-btn down actions-btn' title='Downvotes')
div(class='Vote Vote-down')
svg(width='16', height='16', viewBox='0 0 16 16', fill='none', xmlns='http://www.w3.org/2000/svg')
title Downvotes
| <path fill="none" stroke="#B4B9C2" stroke-width="2" fill-rule="evenodd" clip-rule="evenodd" d="M8.803 13.476a1.2 1.2 0 01-1.606 0 53.03 53.03 0 01-2.364-2.243 29.613 29.613 0 01-2.422-2.722c-.339-.435-.025-1.028.526-1.028h2.397V3.336c0-.524.306-.982.823-1.064A11.874 11.874 0 018 2.15c.829 0 1.427.056 1.843.122.517.082.824.54.824 1.064v4.147h2.396c.552 0 .865.593.527 1.028-.52.669-1.32 1.62-2.423 2.722a53.038 53.038 0 01-2.364 2.243z"></path>
.points - #{comment.downvote_count}
.points = #{comment.point_count}
div(class='GalleryComment-replies')
each reply in comment.comments
+commentbox(reply)
mixin media(m)
div(class='Gallery-Content--mediaContainer')
if m.type === 'video'
.PostVideo
.PostVideo-video-wrapper
video(controls)
source(type=m.mime_type src=util.proxyURL(m.url))
else
div(class='Gallery-Content--media')
div(class='imageContainer')
img(src=util.proxyURL(m.url) title=m.name+' ['+m.metadata.created_at+']')
div(class='Gallery-Content--descr')
div(class='Gallery-Content--title')
span #{m.metadata.title || m.name}
span(class='delimiter') •
span #{m.created_at}
if m.updated_at
span(class='delimiter') •
span #{m.updated_at}
if m.metadata.description
span(class='Linkify') #{m.metadata.description}
html
head
include includes/head.pug
body
include includes/header.pug
.App
.Gallery-MainContainer
.Gallery-contentWrapper
div(class='Gallery-Content')
div(class='Gallery-Header')
div(class='Gallery-Title')
span #{title}
div(class='Gallery-Byline')
if account_id > 0
a(class='author-link' title='View profile of '+account.username, href='/user/'+account.username)
span(class='UserAvatar Avatar', title=account.username, style='background-image: url("' + util.proxyURL(account.avatar_url) + '");')
div(class='Info-Wrapper')
if account_id > 0
div(class='Info')
a(class='author-name' title='View profile of '+account.username, href='/user/'+account.username) #{account.username}
div(class='Meta')
span #{view_count} Views
span(class='delimiter') •
span(title=created_at) #{created_at}
div(class='Gallery-ContentWrapper')
each m in media
+media(m)
if tags
div(class='Gallery-Content--tags')
each tag in tags
a(class='TagPill'
style='background: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)) repeat scroll 0% 0%, rgba(0, 0, 0, 0) url("/' + tag.background_id + '_d.jpg?maxwidth=200&fidelity=grand") repeat scroll 0% 0%;'
href='/t/'+tag.tag) #{tag.tag}
if comments != null
div(class='CommentsList')
div(class='CommentsList-headline')
div(class='CommentsList-headline--counter')
span #{comments.length} Comments
div
div(class='CommentsList-comments')
div(class='CommentsList-comments--container')
each comment in comments
+commentbox(comment)

10
views/partials/footer.hbs Normal file
View File

@ -0,0 +1,10 @@
<br><br><br>
<footer>
<!--<a href="/privacy">
<span class="material-icons-outlined">visibility</span> Privacy
</a>-->
<a href="https://codeberg.org/librarian/librarian" rel="noreferrer">
<span class="material-icons-outlined">code</span> Source Code
</a>
</footer>

View File

@ -1,3 +1,4 @@
<nav> <nav>
<img src="/static/img/rimgo.svg" width="64" height="64" class="logo">
<h2>rimgo</h2> <h2>rimgo</h2>
</nav> </nav>