diff --git a/banner.svg b/banner.svg new file mode 100644 index 0000000..11ae477 --- /dev/null +++ b/banner.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/site/api/api.js b/src/site/api/api.js index 36b519d..d463557 100644 --- a/src/site/api/api.js +++ b/src/site/api/api.js @@ -69,7 +69,8 @@ module.exports = [ features: [ "PAGE_PROFILE", "PAGE_POST", - "API_STATS" + "API_STATS", + "PAGE_HOME" ] } } diff --git a/src/site/api/routes.js b/src/site/api/routes.js index 9a9bda8..c356716 100644 --- a/src/site/api/routes.js +++ b/src/site/api/routes.js @@ -1,8 +1,25 @@ const constants = require("../../lib/constants") const {fetchUser, getOrFetchShortcode} = require("../../lib/collectors") -const {render} = require("pinski/plugins") +const {render, redirect} = require("pinski/plugins") module.exports = [ + { + route: `/u`, methods: ["GET"], code: async ({url}) => { + if (url.searchParams.has("u")) { + let username = url.searchParams.get("u") + username = username.replace(/^(https?:\/\/)?([a-z]+\.)?instagram\.com\//, "") + username = username.replace(/^\@+/, "") + username = username.replace(/\/+$/, "") + return redirect(`/u/${username}`, 301) + } else { + return render(400, "pug/friendlyerror.pug", { + statusCode: 400, + title: "Bad request", + message: "Expected a username." + }) + } + } + }, { route: `/u/(${constants.external.username_regex})`, methods: ["GET"], code: ({url, fill}) => { const params = url.searchParams @@ -53,6 +70,21 @@ module.exports = [ }) } }, + { + route: "/p", methods: ["GET"], code: async ({url}) => { + if (url.searchParams.has("p")) { + let post = url.searchParams.get("p") + post = post.replace(/^(https?:\/\/)?([a-z]+\.)?instagram\.com\/p\//, "") + return redirect(`/p/${post}`, 301) + } else { + return render(400, "pug/friendlyerror.pug", { + statusCode: 400, + title: "Bad request", + message: "Expected a username." + }) + } + } + }, { route: `/p/(${constants.external.shortcode_regex})`, methods: ["GET"], code: ({fill}) => { return getOrFetchShortcode(fill[0]).then(async post => { diff --git a/src/site/html/static/img/banner-min.svg b/src/site/html/static/img/banner-min.svg new file mode 100644 index 0000000..79d9012 --- /dev/null +++ b/src/site/html/static/img/banner-min.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/site/pug/home.pug b/src/site/pug/home.pug new file mode 100644 index 0000000..9479528 --- /dev/null +++ b/src/site/pug/home.pug @@ -0,0 +1,44 @@ +doctype html +html + head + meta(charset="utf-8") + meta(name="viewport" content="width=device-width, initial-scale=1") + title Bibliogram + link(rel="stylesheet" type="text/css" href="/static/css/main.css") + body.homepage + header + h1.banner + img.banner-image(src="/static/img/banner-min.svg") + .go-sections-container + .go-sections + section + h2.title Go to profile + form(method="get" action="/u").pair-entry + input(type="text" name="u" placeholder="Username or URL" autofocus).text + input(type="submit" value="Go").button + section + h2.title Go to post + form(method="get" action="/p").pair-entry + input(type="text" name="p" placeholder="Shortcode or URL").text + input(type="submit" value="Go").button + .about-container + section.about + h2 About Bibliogram + p. + Bibliogram takes data from Instagram's public profile views and produces a friendlier page + that loads faster, proxies images, provides copyable and saveable image sources, eliminates ads, + generates RSS feeds, and doesn't urge you to sign up. + p. + Bibliogram does #[em not] allow you to anonymously post, like, comment, follow, or view private profiles. + It does not preserve deleted posts. + ul.link-list + - + const links = [ + ["https://github.com/cloudrac3r/bibliogram", "GitHub repository"], + ["https://riot.im/app/#/room/#bibliogram:matrix.org", "Discussion room on Matrix"], + ["https://github.com/cloudrac3r/bibliogram/wiki/Home", "Other Bibliogram instances"], + ["https://github.com/cloudrac3r/bibliogram/projects/1?fullscreen=true", "Project board"], + ["https://cadence.moe/about/contact", "Contact the developer"] + ] + each entry in links + li: a(href!=entry[0] target="_blank" rel="noopener noreferrer")= entry[1] diff --git a/src/site/sass/main.sass b/src/site/sass/main.sass index b903799..fce68c1 100644 --- a/src/site/sass/main.sass +++ b/src/site/sass/main.sass @@ -1,5 +1,7 @@ $layout-a-max: 820px $layout-b-min: 821px +$layout-home-a-max: 520px +$layout-home-b-min: 521px body margin: 0 @@ -27,7 +29,10 @@ body line-height: 1 text-decoration: none - &:hover + &.disabled + cursor: default + + &:hover:not(.disabled), &:active, &.clicked color: hsl(106.4, 100%, 12.9%) background: hsl(102.1, 77.2%, 67.3%) border-color: hsl(104, 51.4%, 43.5%) @@ -280,3 +285,104 @@ body .back color: #4a93d2 font-size: 25px + +.homepage + $link-color: #ffb8b8 + + display: flex + flex-direction: column + min-height: 100vh + background-color: #bd4444 + color: #fff + + h1 + font-size: 48px + margin: 0px + + h2 + font-size: 32px + margin: 0px + + a, a:visited + color: $link-color + + .banner + padding: 0px 5px + height: 60vh + display: flex + justify-content: center + align-items: center + + .banner-image + max-width: 100% + + @media screen and (max-width: $layout-home-a-max) + height: 30vh + + .go-sections-container + padding: 0px 10px 50px + + .go-sections + max-width: 900px + margin: 0px auto + display: grid + grid-gap: 10px + grid-template-columns: repeat(2, 1fr) + justify-items: center + + @media screen and (max-width: $layout-home-a-max) + grid-template-columns: 1fr + + .title + text-align: center + margin-bottom: 20px + + .pair-entry + display: flex + + .text, .button + appearance: none + -moz-appearance: none + display: flex + padding: 9px 8px 7px + line-height: 1 + box-sizing: content-box + font-size: 20px + height: 20px + border: 1px solid #333 + + .text + border-radius: 6px 0px 0px 6px + border-right: none + max-width: 230px + width: 30vw + + @media screen and (max-width: 520px) + width: 80vw + + .button + border-radius: 0px 6px 6px 0px + padding-left: 12px + padding-right: 12px + cursor: pointer + background-color: #ffbebe + color: #111 + + &:hover + background-color: #ff7c7c + + .about-container + background-color: #6a2222 + color: #eee + padding: 50px 20px + flex: 1 + min-height: 60vh + + .about + max-width: 700px + margin: 0px auto + line-height: 1.4 + font-size: 20px + + .link-list + color: $link-color diff --git a/src/site/server.js b/src/site/server.js index ca98b75..fc5ac3a 100644 --- a/src/site/server.js +++ b/src/site/server.js @@ -14,6 +14,7 @@ subdirs("pug", (err, dirs) => { //pinski.addRoute("/", "pug/index.pug", "pug") pinski.addRoute("/static/css/main.css", "sass/main.sass", "sass") pinski.addPugDir("pug", dirs) + pinski.addRoute("/", "pug/home.pug", "pug") pinski.addAPIDir("html/static/js/templates/api") pinski.addSassDir("sass") pinski.addAPIDir("api")