mirror of
https://git.sr.ht/~cadence/bibliogram
synced 2025-12-16 03:08:47 +00:00
Create post viewer
This commit is contained in:
@@ -1,30 +1,41 @@
|
||||
const constants = require("../../lib/constants")
|
||||
const {fetchUser} = require("../../lib/collectors")
|
||||
const {fetchUser, fetchShortcode} = require("../../lib/collectors")
|
||||
const {render} = require("pinski/plugins")
|
||||
|
||||
module.exports = [
|
||||
{route: `/u/(${constants.external.username_regex})`, methods: ["GET"], code: async ({url, fill}) => {
|
||||
const params = url.searchParams
|
||||
const user = await fetchUser(fill[0])
|
||||
const page = +params.get("page")
|
||||
if (typeof page === "number" && !isNaN(page) && page >= 1) {
|
||||
await user.timeline.fetchUpToPage(page - 1)
|
||||
{
|
||||
route: `/u/(${constants.external.username_regex})`, methods: ["GET"], code: async ({url, fill}) => {
|
||||
const params = url.searchParams
|
||||
const user = await fetchUser(fill[0])
|
||||
const page = +params.get("page")
|
||||
if (typeof page === "number" && !isNaN(page) && page >= 1) {
|
||||
await user.timeline.fetchUpToPage(page - 1)
|
||||
}
|
||||
return render(200, "pug/user.pug", {url, user})
|
||||
}
|
||||
return render(200, "pug/user.pug", {url, user})
|
||||
}},
|
||||
{route: `/fragment/user/(${constants.external.username_regex})/(\\d+)`, methods: ["GET"], code: async ({url, fill}) => {
|
||||
const user = await fetchUser(fill[0])
|
||||
const pageNumber = +fill[1]
|
||||
const pageIndex = pageNumber - 1
|
||||
await user.timeline.fetchUpToPage(pageIndex)
|
||||
if (user.timeline.pages[pageIndex]) {
|
||||
return render(200, "pug/fragments/timeline_page.pug", {page: user.timeline.pages[pageIndex], pageIndex, user, url})
|
||||
} else {
|
||||
return {
|
||||
statusCode: 400,
|
||||
contentType: "text/html",
|
||||
content: "That page does not exist"
|
||||
},
|
||||
{
|
||||
route: `/fragment/user/(${constants.external.username_regex})/(\\d+)`, methods: ["GET"], code: async ({url, fill}) => {
|
||||
const user = await fetchUser(fill[0])
|
||||
const pageNumber = +fill[1]
|
||||
const pageIndex = pageNumber - 1
|
||||
await user.timeline.fetchUpToPage(pageIndex)
|
||||
if (user.timeline.pages[pageIndex]) {
|
||||
return render(200, "pug/fragments/timeline_page.pug", {page: user.timeline.pages[pageIndex], pageIndex, user, url})
|
||||
} else {
|
||||
return {
|
||||
statusCode: 400,
|
||||
contentType: "text/html",
|
||||
content: "That page does not exist"
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
},
|
||||
{
|
||||
route: `/p/(${constants.external.shortcode_regex})`, methods: ["GET"], code: async ({fill}) => {
|
||||
const post = await fetchShortcode(fill[0])
|
||||
await post.fetchExtendedOwner()
|
||||
return render(200, "pug/post.pug", {post})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -8,7 +8,8 @@ mixin timeline_page(page, pageIndex)
|
||||
span.number Page #{pageNumber}
|
||||
|
||||
.timeline-inner
|
||||
- const suggestedSize = 300
|
||||
- const suggestedSize = 260 //- from css :(
|
||||
each image in page
|
||||
- const thumbnail = image.getSuggestedThumbnail(suggestedSize) //- use this as the src in case there are problems with srcset
|
||||
img(src=image.getProxy(thumbnail.src) alt=image.getAlt() width=thumbnail.config_width height=thumbnail.config_height srcset=image.getSrcset() sizes=`${suggestedSize}px`).image
|
||||
a(href=`/p/${image.data.shortcode}`).sized-link
|
||||
img(src=thumbnail.src alt=image.getAlt() width=thumbnail.config_width height=thumbnail.config_height srcset=image.getSrcset() sizes=image.getSizes()).sized-image
|
||||
|
||||
20
src/site/pug/post.pug
Normal file
20
src/site/pug/post.pug
Normal file
@@ -0,0 +1,20 @@
|
||||
- const numberFormat = new Intl.NumberFormat().format
|
||||
|
||||
doctype html
|
||||
html
|
||||
head
|
||||
meta(charset="utf-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||
title= `${post.getIntroduction()} | Bibliogram`
|
||||
link(rel="stylesheet" type="text/css" href="/static/css/main.css")
|
||||
script(src="/static/js/pagination.js" type="module")
|
||||
body.post-page
|
||||
main.post-page-divider
|
||||
section.description-section
|
||||
header.user-header
|
||||
img(src=post.proxyOwnerProfilePicture width=150 height=150 alt="").pfp
|
||||
a.name(href=`/u/${post.extendedOwner.username}`)= `${post.extendedOwner.full_name} (@${post.extendedOwner.username})`
|
||||
p.description= post.getCaption()
|
||||
section.images-gallery
|
||||
for image in post.getChildren()
|
||||
img(src=image.proxyDisplayURL alt=image.getAlt() width=image.data.dimensions.width height=image.data.dimensions.height).sized-image
|
||||
@@ -37,6 +37,7 @@ html
|
||||
| followed by
|
||||
div.links
|
||||
a(rel="alternate" type="application/rss+xml" href=`/u/${user.data.username}/rss.xml`) RSS
|
||||
a(rel="noreferrer noopener" href=`https://www.instagram.com/${user.data.username}`) instagram.com
|
||||
|
||||
main#timeline.timeline
|
||||
each page, pageIndex in user.timeline.pages
|
||||
|
||||
31
src/site/repl.js
Normal file
31
src/site/repl.js
Normal file
@@ -0,0 +1,31 @@
|
||||
const {instance, pugCache, wss} = require("./passthrough")
|
||||
const {requestCache, timelineImageCache} = require("../lib/collectors")
|
||||
const util = require("util")
|
||||
const repl = require("repl")
|
||||
const vm = require("vm")
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {vm.Context} context
|
||||
* @param {string} filename
|
||||
* @param {(err: Error|null, result: any) => any} callback
|
||||
*/
|
||||
async function customEval(input, context, filename, callback) {
|
||||
let depth = 0
|
||||
if (input == "exit\n") return process.exit()
|
||||
if (input.startsWith(":")) {
|
||||
const depthOverwrite = input.split(" ")[0]
|
||||
depth = +depthOverwrite.slice(1)
|
||||
input = input.slice(depthOverwrite.length + 1)
|
||||
}
|
||||
const result = await eval(input)
|
||||
const output = util.inspect(result, false, depth, true)
|
||||
return callback(undefined, output)
|
||||
}
|
||||
|
||||
function customWriter(output) {
|
||||
return output
|
||||
}
|
||||
|
||||
console.log("REPL started")
|
||||
repl.start({prompt: "b) ", eval: customEval, writer: customWriter}).once("exit", () => process.exit())
|
||||
@@ -33,9 +33,7 @@ body
|
||||
|
||||
.profile-overview
|
||||
text-align: center
|
||||
z-index: 1
|
||||
position: relative
|
||||
contain: paint // </3 css
|
||||
line-height: 1
|
||||
|
||||
@media screen and (max-width: $layout-a-max)
|
||||
@@ -50,29 +48,43 @@ body
|
||||
.profile-sticky
|
||||
position: sticky
|
||||
top: 0
|
||||
bottom: 0
|
||||
height: 100vh
|
||||
box-sizing: border-box
|
||||
overflow-y: auto
|
||||
padding: 10px
|
||||
|
||||
.pfp
|
||||
margin: 25px 0
|
||||
@media screen and (max-width: $layout-a-max)
|
||||
height: unset
|
||||
|
||||
.full-name
|
||||
margin: 0 0 8px
|
||||
font-size: 30px
|
||||
.pfp
|
||||
margin: 25px 0
|
||||
|
||||
.username
|
||||
margin: 0
|
||||
font-size: 20px
|
||||
font-weight: normal
|
||||
.full-name
|
||||
margin: 0 0 8px
|
||||
font-size: 30px
|
||||
|
||||
.profile-counter
|
||||
line-height: 1.3
|
||||
.username
|
||||
margin: 0
|
||||
font-size: 20px
|
||||
font-weight: normal
|
||||
|
||||
.count
|
||||
font-weight: bold
|
||||
.profile-counter
|
||||
line-height: 1.3
|
||||
|
||||
.links
|
||||
margin-top: 20px
|
||||
.count
|
||||
font-weight: bold
|
||||
|
||||
.links
|
||||
margin-top: 20px
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
justify-content: center
|
||||
|
||||
a
|
||||
margin: 5px
|
||||
|
||||
> *:last-child
|
||||
margin-bottom: 10px // because padding-bottom on parent doesn't seem to work.
|
||||
|
||||
.timeline
|
||||
--image-size: 260px
|
||||
@@ -125,17 +137,92 @@ body
|
||||
flex-wrap: wrap
|
||||
margin: 0 auto
|
||||
|
||||
.image
|
||||
@mixin sized()
|
||||
width: $image-size
|
||||
height: $image-size
|
||||
|
||||
.sized-link
|
||||
$margin: 5px
|
||||
|
||||
background-color: rgba(40, 40, 40, 0.25)
|
||||
margin: $margin
|
||||
max-width: $image-size
|
||||
max-height: $image-size
|
||||
width: 100%
|
||||
height: 100%
|
||||
color: #111
|
||||
background-color: rgba(40, 40, 40, 0.25)
|
||||
text-decoration: none
|
||||
@include sized
|
||||
|
||||
&:hover
|
||||
$border-width: 3px
|
||||
margin: $margin - $border-width
|
||||
border: $border-width solid #111
|
||||
|
||||
.sized-image
|
||||
@include sized
|
||||
|
||||
.post-page
|
||||
background-color: #6a6b71
|
||||
|
||||
.post-page-divider
|
||||
display: grid
|
||||
grid-template-columns: 360px auto
|
||||
max-width: 1200px
|
||||
margin: 0 auto
|
||||
min-height: 100vh
|
||||
|
||||
.description-section
|
||||
display: grid
|
||||
align-items: start
|
||||
align-content: normal
|
||||
background-color: #eee
|
||||
position: sticky
|
||||
top: 0
|
||||
height: 100vh
|
||||
overflow-y: auto
|
||||
box-sizing: border-box
|
||||
|
||||
.user-header
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
background-color: #b3b3b3
|
||||
padding: 10px
|
||||
|
||||
.pfp
|
||||
$size: 40px
|
||||
|
||||
width: $size
|
||||
height: $size
|
||||
margin-right: 10px
|
||||
background-color: rgba(40, 40, 40, 0.25)
|
||||
|
||||
.name
|
||||
font-size: 20px
|
||||
color: black
|
||||
text-decoration: none
|
||||
|
||||
&:hover
|
||||
text-decoration: underline
|
||||
|
||||
.description
|
||||
margin: 12px
|
||||
white-space: pre-line
|
||||
font-size: 20px
|
||||
line-height: 1.4
|
||||
|
||||
.images-gallery
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
justify-content: center
|
||||
background-color: #262728
|
||||
padding: 10px
|
||||
|
||||
.sized-image
|
||||
color: #eee
|
||||
background-color: #3b3c3d
|
||||
max-height: 94vh
|
||||
max-width: 100%
|
||||
width: auto
|
||||
height: auto
|
||||
|
||||
&:not(:last-child)
|
||||
margin-bottom: 10px
|
||||
|
||||
@@ -23,4 +23,7 @@ subdirs("pug", (err, dirs) => {
|
||||
require("pinski/plugins").setInstance(pinski)
|
||||
|
||||
Object.assign(passthrough, pinski.getExports())
|
||||
|
||||
console.log("Server started")
|
||||
require("./repl")
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user