mirror of
https://git.sr.ht/~cadence/bibliogram
synced 2024-11-14 12:27:29 +00:00
Create initial language support
Create support for languages, then reformat user, home, and post pages to use it, and create en and en-us language files.
This commit is contained in:
parent
1f76e43446
commit
496d53f47e
@ -7,6 +7,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cd src/site && node server.js",
|
"start": "cd src/site && node server.js",
|
||||||
"assistant": "cd src/site && node assistant.js",
|
"assistant": "cd src/site && node assistant.js",
|
||||||
|
"build-lang": "cd src/lang/utils && node build_base.js",
|
||||||
"test": "tap"
|
"test": "tap"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
46
src/lang/base.js
Normal file
46
src/lang/base.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// This file was automatically generated and its contents will be overwritten later.
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
"go_to_profile": "MISSING STRING: go_to_profile",
|
||||||
|
"go_to_post": "MISSING STRING: go_to_post",
|
||||||
|
"go_username_or_url": "MISSING STRING: go_username_or_url",
|
||||||
|
"go_shortcode_or_url": "MISSING STRING: go_shortcode_or_url",
|
||||||
|
"go_button": "MISSING STRING: go_button",
|
||||||
|
"about_bibliogram_header": "MISSING STRING: about_bibliogram_header",
|
||||||
|
"pug_about_bibliogram_content": locals => "MISSING TEMPLATE: pug_about_bibliogram_content",
|
||||||
|
"about_this_instance_header": "MISSING STRING: about_this_instance_header",
|
||||||
|
"onion_site_available": "MISSING STRING: onion_site_available",
|
||||||
|
"t_settings": "MISSING STRING: t_settings",
|
||||||
|
"t_privacy_policy": "MISSING STRING: t_privacy_policy",
|
||||||
|
"has_not_written_privacy_policy": "MISSING STRING: has_not_written_privacy_policy",
|
||||||
|
"instance_not_blocked": "MISSING STRING: instance_not_blocked",
|
||||||
|
"instance_partially_blocked": "MISSING STRING: instance_partially_blocked",
|
||||||
|
"instance_blocked": "MISSING STRING: instance_blocked",
|
||||||
|
"rss_enabled": "MISSING STRING: rss_enabled",
|
||||||
|
"rss_disabled": "MISSING STRING: rss_disabled",
|
||||||
|
"external_links_header": "MISSING STRING: external_links_header",
|
||||||
|
"source_link": "MISSING STRING: source_link",
|
||||||
|
"matrix_link": "MISSING STRING: matrix_link",
|
||||||
|
"instances_link": "MISSING STRING: instances_link",
|
||||||
|
"contact_link": "MISSING STRING: contact_link",
|
||||||
|
"t_featured_profiles": "MISSING STRING: t_featured_profiles",
|
||||||
|
"featured_profiles_whats_this": "MISSING STRING: featured_profiles_whats_this",
|
||||||
|
"html_featured_profiles_disclaimer": "MISSING STRING: html_featured_profiles_disclaimer",
|
||||||
|
"verified_badge_alt": "MISSING STRING: verified_badge_alt",
|
||||||
|
"verified_badge_title": "MISSING STRING: verified_badge_title",
|
||||||
|
"post_counter_label": "MISSING STRING: post_counter_label",
|
||||||
|
"outgoing_follows_counter_label": "MISSING STRING: outgoing_follows_counter_label",
|
||||||
|
"incoming_follows_counter_label": "MISSING STRING: incoming_follows_counter_label",
|
||||||
|
"t_home": "MISSING STRING: t_home",
|
||||||
|
"tab_timeline": "MISSING STRING: tab_timeline",
|
||||||
|
"tab_igtv": "MISSING STRING: tab_igtv",
|
||||||
|
"next_page_button": "MISSING STRING: next_page_button",
|
||||||
|
"next_page_button_loading": "MISSING STRING: next_page_button_loading",
|
||||||
|
"profile_is_private_notice": "MISSING STRING: profile_is_private_notice",
|
||||||
|
"no_posts_notice": "MISSING STRING: no_posts_notice",
|
||||||
|
"no_more_posts_notice": "MISSING STRING: no_more_posts_notice",
|
||||||
|
"fn_page_divider": () => "MISSING FUNCTION: fn_page_divider",
|
||||||
|
"pug_post_timestamp": locals => "MISSING TEMPLATE: pug_post_timestamp"
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = data
|
3
src/lang/en-us.js
Normal file
3
src/lang/en-us.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
const data = {...require("./en")}
|
||||||
|
|
||||||
|
module.exports = data
|
71
src/lang/en.js
Normal file
71
src/lang/en.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
const compile = require("pug").compile
|
||||||
|
const data = {...require("./base")}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} text
|
||||||
|
*/
|
||||||
|
function pug(text) {
|
||||||
|
let lines = text.split("\n")
|
||||||
|
while (lines[0] === "") lines.shift()
|
||||||
|
const indentLevel = lines[0].match(/^\t*/)[0].length
|
||||||
|
lines = lines.map(l => l.replace(new RegExp(`^\\t{0,${indentLevel}}`), ""))
|
||||||
|
return compile(lines.join("\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
;(() => {
|
||||||
|
data.go_to_profile = "Go to profile"
|
||||||
|
data.go_to_post = "Go to post"
|
||||||
|
data.go_username_or_url = "Username or URL"
|
||||||
|
data.go_shortcode_or_url = "Shortcode or URL"
|
||||||
|
data.go_button = "Go"
|
||||||
|
data.about_bibliogram_header = "About Bibliogram"
|
||||||
|
data.pug_about_bibliogram_content = pug(`
|
||||||
|
p.
|
||||||
|
Bibliogram is a website that takes data from Instagram's public profile views and puts it into
|
||||||
|
a friendlier page that loads faster, gives downloadable images, eliminates ads,
|
||||||
|
generates RSS feeds, and doesn't urge you to sign up. #[a(href=(link_to_featured_profiles ? "#featured-profiles" : "/u/instagram")).example-link See an example.]
|
||||||
|
p.
|
||||||
|
Bibliogram does #[em not] allow you to anonymously post, like, comment, follow, or view private profiles.
|
||||||
|
It does not preserve deleted posts.
|
||||||
|
`)
|
||||||
|
data.about_this_instance_header = "About this instance"
|
||||||
|
data.onion_site_available = "Onion site available"
|
||||||
|
data.t_settings = "Settings"
|
||||||
|
data.t_privacy_policy = "Privacy policy"
|
||||||
|
data.has_not_written_privacy_policy = "Owner has not written a privacy policy"
|
||||||
|
data.instance_not_blocked = "Instance is not blocked"
|
||||||
|
data.instance_partially_blocked = "Instance is partially blocked"
|
||||||
|
data.instance_blocked = "Instance is blocked"
|
||||||
|
data.rss_disabled = "RSS feeds are disabled"
|
||||||
|
data.rss_enabled = "RSS feeds are enabled"
|
||||||
|
data.external_links_header = "External links"
|
||||||
|
data.source_link = "Code on sourcehut"
|
||||||
|
data.matrix_link = "Discussion room on Matrix"
|
||||||
|
data.instances_link = "Other Bibliogram instances"
|
||||||
|
data.contact_link = "Contact the developer"
|
||||||
|
data.t_featured_profiles = "Featured profiles"
|
||||||
|
data.featured_profiles_whats_this = "What's this?"
|
||||||
|
data.html_featured_profiles_disclaimer = pug(`
|
||||||
|
p The owner of this website personally thinks that these profiles are interesting.
|
||||||
|
p These are not endorsements from the Bibliogram project.
|
||||||
|
`)()
|
||||||
|
data.verified_badge_title = "Verified"
|
||||||
|
data.verified_badge_alt = "Verified."
|
||||||
|
data.post_counter_label = "posts"
|
||||||
|
data.outgoing_follows_counter_label = "following"
|
||||||
|
data.incoming_follows_counter_label = "followed by"
|
||||||
|
data.t_home = "Home"
|
||||||
|
data.tab_timeline = "Timeline"
|
||||||
|
data.tab_igtv = "IGTV"
|
||||||
|
data.next_page_button = "Next page"
|
||||||
|
data.next_page_button_loading = "Loading..."
|
||||||
|
data.profile_is_private_notice = "Profile is private."
|
||||||
|
data.no_posts_notice = "No posts."
|
||||||
|
data.no_more_posts_notice = "No more posts."
|
||||||
|
data.fn_page_divider = number => `Page ${number}`
|
||||||
|
data.pug_post_timestamp = pug(`
|
||||||
|
| Posted on #[time(datetime=post.date.toISOString() data-local-date)= post.getDisplayDate()].
|
||||||
|
`)
|
||||||
|
})()
|
||||||
|
|
||||||
|
module.exports = data
|
39
src/lang/index.js
Normal file
39
src/lang/index.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
const base = require("./base")
|
||||||
|
|
||||||
|
class Lang {
|
||||||
|
constructor() {
|
||||||
|
/** @type {Map<string, import("./base")>} */
|
||||||
|
this.backing = new Map()
|
||||||
|
|
||||||
|
this.backing.set("base", require("./base"))
|
||||||
|
|
||||||
|
for (const code of ["en", "en-us"]) {
|
||||||
|
// Assign lang
|
||||||
|
const data = require(`./${code}`)
|
||||||
|
this.backing.set(code, data)
|
||||||
|
// Check properties
|
||||||
|
for (const key of Object.keys(base)) {
|
||||||
|
if (!data[key] || data[key] === base[key]) {
|
||||||
|
console.log(`[!] [${code}] ${key} was not replaced`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} code
|
||||||
|
*/
|
||||||
|
get(code) {
|
||||||
|
if (this.backing.has(code)) {
|
||||||
|
// console.log(`[.] Getting language code ${code}`)
|
||||||
|
return this.backing.get(code)
|
||||||
|
} else {
|
||||||
|
console.log(`[!] WARNING: tried to get missing language code ${code}`)
|
||||||
|
return this.backing.get("base")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const lang = new Lang()
|
||||||
|
|
||||||
|
module.exports = lang
|
7
src/lang/utils/base.template.js
Normal file
7
src/lang/utils/base.template.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// This file is a template.
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
// CONTENT
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = data
|
51
src/lang/utils/base.txt
Normal file
51
src/lang/utils/base.txt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Front page
|
||||||
|
|
||||||
|
# Top section
|
||||||
|
go_to_profile
|
||||||
|
go_to_post
|
||||||
|
go_username_or_url
|
||||||
|
go_shortcode_or_url
|
||||||
|
go_button
|
||||||
|
|
||||||
|
# Bottom section
|
||||||
|
about_bibliogram_header
|
||||||
|
pug_about_bibliogram_content
|
||||||
|
about_this_instance_header
|
||||||
|
onion_site_available
|
||||||
|
t_settings
|
||||||
|
t_privacy_policy
|
||||||
|
has_not_written_privacy_policy
|
||||||
|
instance_not_blocked
|
||||||
|
instance_partially_blocked
|
||||||
|
instance_blocked
|
||||||
|
rss_enabled
|
||||||
|
rss_disabled
|
||||||
|
external_links_header
|
||||||
|
source_link
|
||||||
|
matrix_link
|
||||||
|
instances_link
|
||||||
|
contact_link
|
||||||
|
t_featured_profiles
|
||||||
|
featured_profiles_whats_this
|
||||||
|
html_featured_profiles_disclaimer
|
||||||
|
|
||||||
|
# User page
|
||||||
|
|
||||||
|
verified_badge_alt
|
||||||
|
verified_badge_title
|
||||||
|
post_counter_label
|
||||||
|
outgoing_follows_counter_label
|
||||||
|
incoming_follows_counter_label
|
||||||
|
t_home
|
||||||
|
tab_timeline
|
||||||
|
tab_igtv
|
||||||
|
next_page_button
|
||||||
|
next_page_button_loading
|
||||||
|
profile_is_private_notice
|
||||||
|
no_posts_notice
|
||||||
|
no_more_posts_notice
|
||||||
|
fn_page_divider
|
||||||
|
|
||||||
|
# Post page
|
||||||
|
|
||||||
|
pug_post_timestamp
|
28
src/lang/utils/build_base.js
Normal file
28
src/lang/utils/build_base.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const fs = require("fs").promises
|
||||||
|
const pj = require("path").join
|
||||||
|
|
||||||
|
;(async () => {
|
||||||
|
const contents = await fs.readFile(pj(__dirname, "base.txt"), "utf8")
|
||||||
|
const lines = contents.split("\n")
|
||||||
|
let template = await fs.readFile(pj(__dirname, "base.template.js"), "utf8")
|
||||||
|
|
||||||
|
template = template
|
||||||
|
.replace("// This file is a template.", "// This file was automatically generated and its contents will be overwritten later.")
|
||||||
|
.replace("// CONTENT", lines
|
||||||
|
.filter(l => l && !l.startsWith("#"))
|
||||||
|
.map(l => {
|
||||||
|
if (l.startsWith("pug_")) {
|
||||||
|
return `"${l}": locals => "MISSING TEMPLATE: ${l}"`
|
||||||
|
} else if (l.startsWith("fn_")) {
|
||||||
|
return `"${l}": () => "MISSING FUNCTION: ${l}"`
|
||||||
|
} else {
|
||||||
|
return `"${l}": "MISSING STRING: ${l}"`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.join(",\n\t")
|
||||||
|
)
|
||||||
|
|
||||||
|
await fs.writeFile(pj(__dirname, "../base.js"), template, "utf8")
|
||||||
|
|
||||||
|
console.log("base.js written.")
|
||||||
|
})()
|
@ -107,6 +107,7 @@ let constants = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
default_user_settings: {
|
default_user_settings: {
|
||||||
|
language: "en",
|
||||||
rewrite_youtube: "invidio.us",
|
rewrite_youtube: "invidio.us",
|
||||||
rewrite_twitter: "nitter.net"
|
rewrite_twitter: "nitter.net"
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const constants = require("../../lib/constants")
|
const constants = require("../../lib/constants")
|
||||||
|
const lang = require("../../lang")
|
||||||
const switcher = require("../../lib/utils/torswitcher")
|
const switcher = require("../../lib/utils/torswitcher")
|
||||||
const {fetchUser, getOrFetchShortcode, userRequestCache, history, assistantSwitcher} = require("../../lib/collectors")
|
const {fetchUser, getOrFetchShortcode, userRequestCache, history, assistantSwitcher} = require("../../lib/collectors")
|
||||||
const {render, redirect, getStaticURL} = require("pinski/plugins")
|
const {render, redirect, getStaticURL} = require("pinski/plugins")
|
||||||
@ -112,7 +113,8 @@ module.exports = [
|
|||||||
username,
|
username,
|
||||||
expiresMinutes: userRequestCache.getTtl("user/"+username, 1000*60),
|
expiresMinutes: userRequestCache.getTtl("user/"+username, 1000*60),
|
||||||
getStaticURL,
|
getStaticURL,
|
||||||
settings
|
settings,
|
||||||
|
lang
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (error === constants.symbols.extractor_results.AGE_RESTRICTED) {
|
} else if (error === constants.symbols.extractor_results.AGE_RESTRICTED) {
|
||||||
@ -179,7 +181,7 @@ module.exports = [
|
|||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
content: {
|
content: {
|
||||||
title: getPageTitle(post),
|
title: getPageTitle(post),
|
||||||
html: pugCache.get("pug/fragments/post.pug").web({post, settings, getStaticURL})
|
html: pugCache.get("pug/fragments/post.pug").web({lang, post, settings, getStaticURL})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
@ -57,7 +57,7 @@ class ElemJS {
|
|||||||
event(name, callback) {
|
event(name, callback) {
|
||||||
this.element.addEventListener(name, event => callback(event))
|
this.element.addEventListener(name, event => callback(event))
|
||||||
}
|
}
|
||||||
child(toAdd, position) {
|
child(toAdd, position = undefined) {
|
||||||
if (typeof(toAdd) == "object") {
|
if (typeof(toAdd) == "object") {
|
||||||
toAdd.parent = this;
|
toAdd.parent = this;
|
||||||
if (typeof(position) == "number" && position >= 0) {
|
if (typeof(position) == "number" && position >= 0) {
|
||||||
|
@ -75,7 +75,7 @@ class NextPage extends FreezeWidth {
|
|||||||
fetch() {
|
fetch() {
|
||||||
if (this.fetching) return
|
if (this.fetching) return
|
||||||
this.fetching = true
|
this.fetching = true
|
||||||
this.freeze("Loading...")
|
this.freeze(this.element.getAttribute("data-loading-text"))
|
||||||
const type = this.element.getAttribute("data-type")
|
const type = this.element.getAttribute("data-type")
|
||||||
|
|
||||||
return fetch(`/fragment/user/${this.element.getAttribute("data-username")}/${this.nextPageNumber}?type=${type}`).then(res => res.text()).then(text => {
|
return fetch(`/fragment/user/${this.element.getAttribute("data-username")}/${this.nextPageNumber}?type=${type}`).then(res => res.text()).then(text => {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//- Needs post
|
//- Needs post
|
||||||
|
|
||||||
|
- const ll = lang.get(settings.language)
|
||||||
|
|
||||||
include ../includes/post.pug
|
include ../includes/post.pug
|
||||||
|
|
||||||
+post(post, true)
|
+post(post, true)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//- Needs user, selectedTimeline, url, type
|
//- Needs user, selectedTimeline, url, type
|
||||||
|
|
||||||
|
- const ll = lang.get(settings.language)
|
||||||
|
|
||||||
include ../includes/timeline_page.pug
|
include ../includes/timeline_page.pug
|
||||||
include ../includes/next_page_button.pug
|
include ../includes/next_page_button.pug
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//- Needs rssEnabled, allUnblocked, torAvailable, hasPrivacyPolicy, onionLocation
|
//- Needs rssEnabled, allUnblocked, torAvailable, hasPrivacyPolicy, onionLocation
|
||||||
|
|
||||||
|
- const ll = lang.get(settings.language)
|
||||||
|
|
||||||
doctype html
|
doctype html
|
||||||
html
|
html
|
||||||
head
|
head
|
||||||
@ -13,57 +15,53 @@ html
|
|||||||
.go-sections-container
|
.go-sections-container
|
||||||
.go-sections
|
.go-sections
|
||||||
section
|
section
|
||||||
h2.title Go to profile
|
h2.title= ll.go_to_profile
|
||||||
form(method="get" action="/u").pair-entry
|
form(method="get" action="/u").pair-entry
|
||||||
input(type="text" name="u" placeholder="Username or URL").text
|
input(type="text" name="u" placeholder=ll.go_username_or_url).text
|
||||||
input(type="submit" value="Go").button
|
input(type="submit" value=ll.go_button).button
|
||||||
section
|
section
|
||||||
h2.title Go to post
|
h2.title= ll.go_to_post
|
||||||
form(method="get" action="/p").pair-entry
|
form(method="get" action="/p").pair-entry
|
||||||
input(type="text" name="p" placeholder="Shortcode or URL").text
|
input(type="text" name="p" placeholder=ll.go_shortcode_or_url).text
|
||||||
input(type="submit" value="Go").button
|
input(type="submit" value=ll.go_button).button
|
||||||
|
|
||||||
.about-container
|
.about-container
|
||||||
section.about
|
section.about
|
||||||
h2 About Bibliogram
|
h2= ll.about_bibliogram_header
|
||||||
p.
|
!= ll.pug_about_bibliogram_content(constants.featured_profiles.length)
|
||||||
Bibliogram is a website that takes data from Instagram's public profile views and puts it into
|
h2= ll.about_this_instance_header
|
||||||
a friendlier page that loads faster, gives downloadable images, eliminates ads,
|
|
||||||
generates RSS feeds, and doesn't urge you to sign up. #[a(href=(constants.featured_profiles.length ? "#featured-profiles" : "/u/instagram")).example-link See an example.]
|
|
||||||
p.
|
|
||||||
Bibliogram does #[em not] allow you to anonymously post, like, comment, follow, or view private profiles.
|
|
||||||
It does not preserve deleted posts.
|
|
||||||
|
|
||||||
h2 About this instance
|
|
||||||
ul
|
ul
|
||||||
if onionLocation
|
if onionLocation
|
||||||
li: a(href=onionLocation) Onion site available
|
li: a(href=onionLocation)= ll.onion_site_available
|
||||||
li: a(href=settingsReferrer) Settings
|
li: a(href=settingsReferrer)= ll.t_settings
|
||||||
if hasPrivacyPolicy
|
if hasPrivacyPolicy
|
||||||
li: a(href="/privacy") Privacy policy
|
li: a(href="/privacy")= ll.t_privacy_policy
|
||||||
else
|
else
|
||||||
li Owner has not written a privacy policy
|
li= ll.has_not_written_privacy_policy
|
||||||
if allUnblocked
|
if allUnblocked
|
||||||
li Instance is not blocked
|
li= ll.instance_not_blocked
|
||||||
else
|
else
|
||||||
li: a(href="https://git.sr.ht/~cadence/bibliogram-docs/tree/master/docs/Instagram%20rate%20limits.md#tldr-what-does-it-mean-if-an-instance-is-blocked") Instance is partially blocked
|
li: a(href="https://git.sr.ht/~cadence/bibliogram-docs/tree/master/docs/Instagram%20rate%20limits.md#tldr-what-does-it-mean-if-an-instance-is-blocked")= ll.instance_partially_blocked
|
||||||
li RSS feeds are #{rssEnabled ? "enabled" : "disabled"}
|
if rssEnabled
|
||||||
|
li= ll.rss_enabled
|
||||||
|
else
|
||||||
|
li= ll.rss_disabled
|
||||||
|
|
||||||
h2 External links
|
h2= ll.external_links_header
|
||||||
ul
|
ul
|
||||||
-
|
-
|
||||||
const links = [
|
const links = [
|
||||||
["https://sr.ht/~cadence/bibliogram/", "Code on sourcehut", "noopener noreferrer"],
|
["https://sr.ht/~cadence/bibliogram/", ll.source_link, "noopener noreferrer"],
|
||||||
["https://matrix.to/#/#bibliogram:matrix.org", "Discussion room on Matrix", "noopener noreferrer"],
|
["https://matrix.to/#/#bibliogram:matrix.org", ll.matrix_link, "noopener noreferrer"],
|
||||||
["https://git.sr.ht/~cadence/bibliogram-docs/tree/master/docs/Instances.md", "Other Bibliogram instances", "noopener noreferrer"],
|
["https://git.sr.ht/~cadence/bibliogram-docs/tree/master/docs/Instances.md", ll.instances_link, "noopener noreferrer"],
|
||||||
["https://cadence.moe/about/contact", "Contact the developer", "noopener noreferrer"]
|
["https://cadence.moe/about/contact", ll.contact_link, "noopener noreferrer"]
|
||||||
]
|
]
|
||||||
each entry in links
|
each entry in links
|
||||||
li: a(href!=entry[0] target="_blank" rel=entry[2])= entry[1]
|
li: a(href!=entry[0] target="_blank" rel=entry[2])= entry[1]
|
||||||
|
|
||||||
if constants.featured_profiles.length
|
if constants.featured_profiles.length
|
||||||
.featured-profiles#featured-profiles
|
.featured-profiles#featured-profiles
|
||||||
h2.featured-profiles-header Featured profiles
|
h2.featured-profiles-header= ll.featured_profiles_header
|
||||||
|
|
||||||
table.featured-profile-table
|
table.featured-profile-table
|
||||||
tbody
|
tbody
|
||||||
@ -73,7 +71,5 @@ html
|
|||||||
td= profile.description
|
td= profile.description
|
||||||
|
|
||||||
details
|
details
|
||||||
summary What's this?
|
summary= ll.featured_profiles_whats_this
|
||||||
.details-content
|
.details-content= ll.html_featured_profiles_disclaimer
|
||||||
p The owner of this website personally thinks that these profiles are interesting.
|
|
||||||
p These are not endorsements from the Bibliogram project.
|
|
||||||
|
@ -4,8 +4,14 @@ mixin next_page_button(user, selectedTimeline, url, type)
|
|||||||
-
|
-
|
||||||
const nu = new URL(url)
|
const nu = new URL(url)
|
||||||
nu.searchParams.set("page", selectedTimeline.pages.length+1)
|
nu.searchParams.set("page", selectedTimeline.pages.length+1)
|
||||||
a(href=`${nu.search}#page-${selectedTimeline.pages.length+1}` data-page=(selectedTimeline.pages.length+1) data-username=(user.data.username) data-type=type)#next-page.next-page Next page
|
a(
|
||||||
|
href=`${nu.search}#page-${selectedTimeline.pages.length+1}`
|
||||||
|
data-page=(selectedTimeline.pages.length+1)
|
||||||
|
data-username=(user.data.username)
|
||||||
|
data-type=type
|
||||||
|
data-loading-text=ll.next_page_button_loading
|
||||||
|
)#next-page.next-page= ll.next_page_button
|
||||||
else
|
else
|
||||||
div
|
div
|
||||||
div.page-number.no-more-pages
|
div.page-number.no-more-pages
|
||||||
span.number No more posts.
|
span.number= ll.no_more_posts_notice
|
||||||
|
@ -39,7 +39,7 @@ mixin post(post, headerWithNavigation)
|
|||||||
if caption
|
if caption
|
||||||
p.description= caption
|
p.description= caption
|
||||||
p.description
|
p.description
|
||||||
span Posted on #[time(datetime=post.date.toISOString() data-local-date)= post.getDisplayDate()].
|
span!= ll.pug_post_timestamp({post})
|
||||||
|
|
||||||
section.images-gallery
|
section.images-gallery
|
||||||
for entry in post.children
|
for entry in post.children
|
||||||
|
@ -5,7 +5,7 @@ mixin timeline_page(page, pageIndex)
|
|||||||
- const pageNumber = pageIndex + 1
|
- const pageNumber = pageIndex + 1
|
||||||
if pageNumber > 1
|
if pageNumber > 1
|
||||||
header.page-number(id=`page-${pageNumber}`)
|
header.page-number(id=`page-${pageNumber}`)
|
||||||
span.number Page #{pageNumber}
|
span.number= ll.fn_page_divider(pageNumber)
|
||||||
|
|
||||||
.timeline-inner(class=`${settings.timeline_columns}-columns`)
|
.timeline-inner(class=`${settings.timeline_columns}-columns`)
|
||||||
- const suggestedSize = 260 //- from css :(
|
- const suggestedSize = 260 //- from css :(
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//- Needs website_origin, title, post, settings
|
//- Needs website_origin, title, post, settings
|
||||||
|
|
||||||
|
- const ll = lang.get(settings.language)
|
||||||
|
|
||||||
include includes/post
|
include includes/post
|
||||||
|
|
||||||
doctype html
|
doctype html
|
||||||
|
@ -45,7 +45,7 @@ html
|
|||||||
h1 Settings
|
h1 Settings
|
||||||
|
|
||||||
+fieldset("Features")
|
+fieldset("Features")
|
||||||
+select("language", "Language", true, [
|
+select("language", "Language", false, [
|
||||||
{value: "en", text: "English (International)"},
|
{value: "en", text: "English (International)"},
|
||||||
{value: "en-us", text: "English (US)"}
|
{value: "en-us", text: "English (US)"}
|
||||||
])
|
])
|
||||||
|
@ -5,13 +5,14 @@ include includes/next_page_button.pug
|
|||||||
include includes/display_structured
|
include includes/display_structured
|
||||||
include includes/feed_link
|
include includes/feed_link
|
||||||
|
|
||||||
|
- const ll = lang.get(settings.language)
|
||||||
- const numberFormat = new Intl.NumberFormat().format
|
- const numberFormat = new Intl.NumberFormat().format
|
||||||
|
|
||||||
mixin selector-button(text, selectorType, urlSuffix)
|
mixin selector-button(text, selectorType, urlSuffix)
|
||||||
a(href=(type !== selectorType && `/u/${user.data.username}${urlSuffix}`) class=(type === selectorType && "active")).selector= text
|
a(href=(type !== selectorType && `/u/${user.data.username}${urlSuffix}`) class=(type === selectorType && "active")).selector= text
|
||||||
|
|
||||||
mixin verified-badge(classes)
|
mixin verified-badge(classes)
|
||||||
img.verified-badge(class=classes src=getStaticURL("html", "/static/img/verified.svg") width=19 height=19 alt="Verified." title="Verified")
|
img.verified-badge(class=classes src=getStaticURL("html", "/static/img/verified.svg") width=19 height=19 alt=ll.verified_badge_alt title=ll.verified_badge_title)
|
||||||
|
|
||||||
doctype html
|
doctype html
|
||||||
html
|
html
|
||||||
@ -42,7 +43,7 @@ html
|
|||||||
a(href="/").nav-icon-link
|
a(href="/").nav-icon-link
|
||||||
img(src="/static/img/logo-circle-min.svg" alt="Bibliogram").logo
|
img(src="/static/img/logo-circle-min.svg" alt="Bibliogram").logo
|
||||||
a(href=settingsReferrer).nav-icon-link
|
a(href=settingsReferrer).nav-icon-link
|
||||||
img(src="/static/img/settings.svg" alt="Settings").settings
|
img(src="/static/img/settings.svg" alt=ll.t_settings).settings
|
||||||
.main-divider
|
.main-divider
|
||||||
header.profile-overview
|
header.profile-overview
|
||||||
.profile-sticky
|
.profile-sticky
|
||||||
@ -71,12 +72,18 @@ html
|
|||||||
p.website
|
p.website
|
||||||
a(href=userURL)= userURL
|
a(href=userURL)= userURL
|
||||||
if user.posts != undefined
|
if user.posts != undefined
|
||||||
div.profile-counter #[span(data-numberformat=user.posts).count #{numberFormat(user.posts)}] posts
|
div.profile-counter
|
||||||
|
| #[span(data-numberformat=user.posts).count #{numberFormat(user.posts)} ]
|
||||||
|
= ll.post_counter_label
|
||||||
if followerCountsAvailable
|
if followerCountsAvailable
|
||||||
if user.following != undefined
|
if user.following != undefined
|
||||||
div.profile-counter #[span(data-numberformat=user.following).count #{numberFormat(user.following)}] following
|
div.profile-counter
|
||||||
|
| #[span(data-numberformat=user.following).count #{numberFormat(user.following)} ]
|
||||||
|
= ll.outgoing_follows_counter_label
|
||||||
if user.followedBy != undefined
|
if user.followedBy != undefined
|
||||||
div.profile-counter #[span(data-numberformat=user.followedBy).count #{numberFormat(user.followedBy)}] followed by
|
div.profile-counter
|
||||||
|
| #[span(data-numberformat=user.followedBy).count #{numberFormat(user.followedBy)} ]
|
||||||
|
= ll.incoming_follows_counter_label
|
||||||
else
|
else
|
||||||
div.profile-counter.not-available Followers not available.
|
div.profile-counter.not-available Followers not available.
|
||||||
.links
|
.links
|
||||||
@ -86,15 +93,15 @@ html
|
|||||||
a(rel="noreferrer noopener" href=`https://www.instagram.com/${user.data.username}` target="_blank") instagram.com
|
a(rel="noreferrer noopener" href=`https://www.instagram.com/${user.data.username}` target="_blank") instagram.com
|
||||||
section.bibliogram-meta
|
section.bibliogram-meta
|
||||||
.links
|
.links
|
||||||
a(href="/") Home
|
a(href="/")= ll.t_home
|
||||||
a(href=settingsReferrer) Settings
|
a(href=settingsReferrer)= ll.t_settings
|
||||||
|
|
||||||
- const hasPosts = !user.data.is_private && selectedTimeline.pages.length && selectedTimeline.pages[0].length
|
- const hasPosts = !user.data.is_private && selectedTimeline.pages.length && selectedTimeline.pages[0].length
|
||||||
.timeline-section
|
.timeline-section
|
||||||
.selector-container
|
.selector-container
|
||||||
+selector-button("Timeline", "timeline", "")
|
+selector-button(ll.tab_timeline, "timeline", "")
|
||||||
if user.data.has_channel !== false
|
if user.data.has_channel !== false
|
||||||
+selector-button("IGTV", "igtv", "/channel")
|
+selector-button(ll.tab_igtv, "igtv", "/channel")
|
||||||
|
|
||||||
main(class=hasPosts ? "" : "no-posts")#timeline.timeline
|
main(class=hasPosts ? "" : "no-posts")#timeline.timeline
|
||||||
if hasPosts
|
if hasPosts
|
||||||
@ -106,6 +113,6 @@ html
|
|||||||
div.page-number
|
div.page-number
|
||||||
span.number
|
span.number
|
||||||
if user.data.is_private
|
if user.data.is_private
|
||||||
| Profile is private.
|
= ll.profile_is_private_notice
|
||||||
else
|
else
|
||||||
| No posts.
|
= ll.no_posts_notice
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const {Pinski} = require("pinski")
|
const {Pinski} = require("pinski")
|
||||||
const {subdirs} = require("node-dir")
|
const {subdirs} = require("node-dir")
|
||||||
const constants = require("../lib/constants")
|
const constants = require("../lib/constants")
|
||||||
|
const lang = require("../lang")
|
||||||
|
|
||||||
const passthrough = require("./passthrough")
|
const passthrough = require("./passthrough")
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ subdirs("pug", async (err, dirs) => {
|
|||||||
|
|
||||||
const plugins = require("pinski/plugins")
|
const plugins = require("pinski/plugins")
|
||||||
plugins.setInstance(pinski)
|
plugins.setInstance(pinski)
|
||||||
Object.assign(pinski.pugDefaultLocals, {constants})
|
Object.assign(pinski.pugDefaultLocals, {constants, lang})
|
||||||
Object.assign(passthrough, pinski.getExports())
|
Object.assign(passthrough, pinski.getExports())
|
||||||
|
|
||||||
console.log("[.] Server started")
|
console.log("[.] Server started")
|
||||||
|
Loading…
Reference in New Issue
Block a user