mirror of
https://git.sr.ht/~cadence/cloudtube
synced 2024-11-26 09:27:30 +00:00
Add home page and search page
This commit is contained in:
parent
cbc3a2bf67
commit
2cc6a2912a
14
api/search.js
Normal file
14
api/search.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
const fetch = require("node-fetch")
|
||||||
|
const {render} = require("pinski/plugins")
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
route: "/(?:search|results)", methods: ["GET"], code: async ({url}) => {
|
||||||
|
const query = url.searchParams.get("q") || url.searchParams.get("search_query")
|
||||||
|
const fetchURL = new URL("http://localhost:3000/api/v1/search")
|
||||||
|
fetchURL.searchParams.set("q", query)
|
||||||
|
const results = await fetch(fetchURL.toString()).then(res => res.json())
|
||||||
|
return render(200, "pug/search.pug", {results})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
11
pug/home.pug
Normal file
11
pug/home.pug
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
extends includes/layout.pug
|
||||||
|
|
||||||
|
block content
|
||||||
|
main.home-page
|
||||||
|
h1.top-header CloudTube
|
||||||
|
h2.tagline An alternative front-end for YouTube.
|
||||||
|
.encouraging-message
|
||||||
|
p You're in control. Watch things your way.
|
||||||
|
p Go on. What do you want to watch?
|
||||||
|
form(method="get" action="/search").encouraging-search-form
|
||||||
|
input(type="text" name="q" placeholder="I'd like to watch..." autocomplete="off").search.base-border-look
|
@ -10,6 +10,7 @@ html
|
|||||||
body.show-focus
|
body.show-focus
|
||||||
nav.main-nav
|
nav.main-nav
|
||||||
a(href="/").link.home CloudTube
|
a(href="/").link.home CloudTube
|
||||||
|
form(method="get" action="/search").search-form
|
||||||
input(type="text" placeholder="Search" name="q" autocomplete="off").search
|
input(type="text" placeholder="Search" name="q" autocomplete="off").search
|
||||||
|
|
||||||
block content
|
block content
|
||||||
|
16
pug/includes/video-list-item.pug
Normal file
16
pug/includes/video-list-item.pug
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
mixin video_list_item(video)
|
||||||
|
- let link = `/watch?v=${video.videoId}`
|
||||||
|
a(href=link).thumbnail
|
||||||
|
img(src=`https://i.ytimg.com/vi/${video.videoId}/mqdefault.jpg` width=320 height=180 alt="").image
|
||||||
|
span.duration= video.second__lengthText
|
||||||
|
.info
|
||||||
|
div.title: a(href=link).title-link= video.title
|
||||||
|
div.author-line
|
||||||
|
a(href=`/channel/${video.authorId}`).author= video.author
|
||||||
|
if video.publishedText
|
||||||
|
= ` • `
|
||||||
|
span.published= video.publishedText
|
||||||
|
= ` • `
|
||||||
|
span.views= video.viewCountText || video.second__viewCountText
|
||||||
|
if video.descriptionHtml
|
||||||
|
div.description!= video.descriptionHtml
|
9
pug/search.pug
Normal file
9
pug/search.pug
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
extends includes/layout.pug
|
||||||
|
|
||||||
|
include includes/video-list-item.pug
|
||||||
|
|
||||||
|
block content
|
||||||
|
main.search-page
|
||||||
|
each result in results
|
||||||
|
.search-result
|
||||||
|
+video_list_item(result)
|
@ -1,5 +1,7 @@
|
|||||||
extends includes/layout.pug
|
extends includes/layout.pug
|
||||||
|
|
||||||
|
include includes/video-list-item.pug
|
||||||
|
|
||||||
block head
|
block head
|
||||||
title= video.title
|
title= video.title
|
||||||
script(type="module" src=getStaticURL("html", "/static/js/player.js"))
|
script(type="module" src=getStaticURL("html", "/static/js/player.js"))
|
||||||
@ -56,13 +58,4 @@ block content
|
|||||||
h2.related-header Related videos
|
h2.related-header Related videos
|
||||||
each r in video.recommendedVideos
|
each r in video.recommendedVideos
|
||||||
.related-video
|
.related-video
|
||||||
- let link = `/watch?v=${r.videoId}`
|
+video_list_item(r)
|
||||||
a(href=link).thumbnail
|
|
||||||
img(src=`https://i.ytimg.com/vi/${r.videoId}/mqdefault.jpg` width=320 height=180 alt="").image
|
|
||||||
span.duration= r.second__lengthText
|
|
||||||
.info
|
|
||||||
div.title: a(href=link).title-link= r.title
|
|
||||||
div.author-line
|
|
||||||
a(href=`/channel/${authorId}`).author= r.author
|
|
||||||
= ` • `
|
|
||||||
span.views= r.viewCountText
|
|
||||||
|
@ -18,6 +18,9 @@ input, select, button
|
|||||||
button
|
button
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
|
|
||||||
|
:focus
|
||||||
|
outline: none
|
||||||
|
|
||||||
:-moz-focusring
|
:-moz-focusring
|
||||||
outline: none
|
outline: none
|
||||||
|
|
||||||
|
36
sass/includes/home-page.sass
Normal file
36
sass/includes/home-page.sass
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
@use "colors.sass" as c
|
||||||
|
|
||||||
|
.home-page
|
||||||
|
padding: 40px
|
||||||
|
|
||||||
|
.top-header
|
||||||
|
font-size: 48px
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
.tagline
|
||||||
|
font-size: 30px
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
.encouraging-message
|
||||||
|
max-width: max-content
|
||||||
|
margin: 0 auto
|
||||||
|
text-align: center
|
||||||
|
padding: 16px
|
||||||
|
border-radius: 4px
|
||||||
|
font-size: 20px
|
||||||
|
background-color: c.$bg-darker
|
||||||
|
color: c.$fg-main
|
||||||
|
|
||||||
|
p
|
||||||
|
margin: 0 32px
|
||||||
|
|
||||||
|
&:not(:last-child)
|
||||||
|
margin-bottom: 0.6em
|
||||||
|
|
||||||
|
.encouraging-search-form
|
||||||
|
display: flex
|
||||||
|
|
||||||
|
.search
|
||||||
|
margin-top: 16px
|
||||||
|
flex: 1
|
||||||
|
font-size: 18px
|
44
sass/includes/search-page.sass
Normal file
44
sass/includes/search-page.sass
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
@use "video-list-item.sass" as *
|
||||||
|
@use "colors.sass" as c
|
||||||
|
|
||||||
|
.search-page
|
||||||
|
padding: 40px 20px 20px
|
||||||
|
max-width: 900px
|
||||||
|
margin: 0 auto
|
||||||
|
|
||||||
|
.search-result
|
||||||
|
@include video-list-item
|
||||||
|
|
||||||
|
grid-gap: 16px
|
||||||
|
grid-template-columns: 240px 1fr
|
||||||
|
margin-bottom: 20px
|
||||||
|
overflow: hidden
|
||||||
|
|
||||||
|
.image
|
||||||
|
width: 240px
|
||||||
|
height: 135px
|
||||||
|
|
||||||
|
.duration
|
||||||
|
font-size: 17px
|
||||||
|
padding: 4px 5px
|
||||||
|
right: 5px
|
||||||
|
bottom: 5px
|
||||||
|
|
||||||
|
.title
|
||||||
|
font-size: 24px
|
||||||
|
|
||||||
|
.author-line
|
||||||
|
font-size: 15px
|
||||||
|
color: c.$fg-main
|
||||||
|
|
||||||
|
.author
|
||||||
|
color: c.$fg-main
|
||||||
|
|
||||||
|
.description
|
||||||
|
margin-top: 16px
|
||||||
|
font-size: 15px
|
||||||
|
color: c.$fg-dim
|
||||||
|
|
||||||
|
b
|
||||||
|
font-weight: normal
|
||||||
|
color: c.$fg-main
|
50
sass/includes/video-list-item.sass
Normal file
50
sass/includes/video-list-item.sass
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
@use "colors.sass" as c
|
||||||
|
|
||||||
|
@mixin video-list-item
|
||||||
|
display: grid
|
||||||
|
grid-template-columns: 160px 1fr
|
||||||
|
grid-gap: 8px
|
||||||
|
align-items: start
|
||||||
|
align-content: start
|
||||||
|
margin-bottom: 12px
|
||||||
|
|
||||||
|
.thumbnail
|
||||||
|
position: relative
|
||||||
|
display: flex
|
||||||
|
background: c.$bg-darkest
|
||||||
|
|
||||||
|
.image
|
||||||
|
width: 160px
|
||||||
|
height: 90px
|
||||||
|
|
||||||
|
.duration
|
||||||
|
position: absolute
|
||||||
|
bottom: 3px
|
||||||
|
right: 3px
|
||||||
|
color: c.$fg-bright
|
||||||
|
font-size: 14px
|
||||||
|
background: rgba(20, 20, 20, 0.85)
|
||||||
|
line-height: 1
|
||||||
|
padding: 3px 5px 4px
|
||||||
|
border-radius: 4px
|
||||||
|
|
||||||
|
.title
|
||||||
|
font-size: 15px
|
||||||
|
line-height: 1.2
|
||||||
|
|
||||||
|
.title-link
|
||||||
|
color: c.$fg-main
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
|
.author-line
|
||||||
|
margin-top: 4px
|
||||||
|
font-size: 15px
|
||||||
|
color: c.$fg-dim
|
||||||
|
|
||||||
|
.author
|
||||||
|
color: c.$fg-dim
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
|
&:hover, &:active
|
||||||
|
color: c.$fg-bright
|
||||||
|
text-decoration: underline
|
@ -1,4 +1,5 @@
|
|||||||
@use "colors.sass" as c
|
@use "colors.sass" as c
|
||||||
|
@use "video-list-item.sass" as *
|
||||||
|
|
||||||
.video-page
|
.video-page
|
||||||
display: grid
|
display: grid
|
||||||
@ -44,7 +45,8 @@
|
|||||||
.info-secondary
|
.info-secondary
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
align-items: end
|
align-items: flex-end
|
||||||
|
text-align: right
|
||||||
margin-top: 6px
|
margin-top: 6px
|
||||||
margin-left: 6px
|
margin-left: 6px
|
||||||
|
|
||||||
@ -68,50 +70,4 @@
|
|||||||
font-size: 26px
|
font-size: 26px
|
||||||
|
|
||||||
.related-video
|
.related-video
|
||||||
display: grid
|
@include video-list-item
|
||||||
grid-template-columns: 160px 1fr
|
|
||||||
grid-gap: 8px
|
|
||||||
align-items: start
|
|
||||||
align-content: start
|
|
||||||
margin-bottom: 16px
|
|
||||||
|
|
||||||
.thumbnail
|
|
||||||
position: relative
|
|
||||||
display: flex
|
|
||||||
background: c.$bg-darkest
|
|
||||||
|
|
||||||
.image
|
|
||||||
width: 160px
|
|
||||||
height: 90px
|
|
||||||
|
|
||||||
.duration
|
|
||||||
position: absolute
|
|
||||||
bottom: 3px
|
|
||||||
right: 3px
|
|
||||||
color: c.$fg-bright
|
|
||||||
font-size: 14px
|
|
||||||
background: rgba(20, 20, 20, 0.85)
|
|
||||||
line-height: 1
|
|
||||||
padding: 3px 5px 4px
|
|
||||||
border-radius: 4px
|
|
||||||
|
|
||||||
.title
|
|
||||||
font-size: 15px
|
|
||||||
line-height: 1.2
|
|
||||||
|
|
||||||
.title-link
|
|
||||||
color: c.$fg-main
|
|
||||||
text-decoration: none
|
|
||||||
|
|
||||||
.author-line
|
|
||||||
margin-top: 4px
|
|
||||||
font-size: 15px
|
|
||||||
color: c.$fg-dim
|
|
||||||
|
|
||||||
.author
|
|
||||||
color: c.$fg-dim
|
|
||||||
text-decoration: none
|
|
||||||
|
|
||||||
&:hover, &:active
|
|
||||||
color: c.$fg-bright
|
|
||||||
text-decoration: underline
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
@use "includes/colors.sass" as c
|
@use "includes/colors.sass" as c
|
||||||
@use "sass:selector"
|
@use "sass:selector"
|
||||||
@use "includes/video-page.sass"
|
@use "includes/video-page.sass"
|
||||||
|
@use "includes/search-page.sass"
|
||||||
|
@use "includes/home-page.sass"
|
||||||
|
|
||||||
@font-face
|
@font-face
|
||||||
font-family: "Bariol"
|
font-family: "Bariol"
|
||||||
@ -52,6 +54,9 @@
|
|||||||
&:active
|
&:active
|
||||||
background-color: c.$bg-dark
|
background-color: c.$bg-dark
|
||||||
|
|
||||||
|
.base-border-look
|
||||||
|
@include border-button
|
||||||
|
|
||||||
.border-look
|
.border-look
|
||||||
@include border-button
|
@include border-button
|
||||||
@include button-size
|
@include button-size
|
||||||
@ -78,8 +83,14 @@
|
|||||||
&:focus, &:hover
|
&:focus, &:hover
|
||||||
background-color: c.$bg-accent-x
|
background-color: c.$bg-accent-x
|
||||||
|
|
||||||
|
.search-form
|
||||||
|
display: flex
|
||||||
|
flex: 1
|
||||||
|
align-items: center
|
||||||
|
|
||||||
.search
|
.search
|
||||||
@include button-bg
|
@include button-bg
|
||||||
|
padding: 10px
|
||||||
flex: 1
|
flex: 1
|
||||||
margin: 1px
|
margin: 1px
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ server.addSassDir("sass", ["sass/includes"])
|
|||||||
server.addRoute("/static/css/main.css", "sass/main.sass", "sass")
|
server.addRoute("/static/css/main.css", "sass/main.sass", "sass")
|
||||||
|
|
||||||
server.addPugDir("pug", ["pug/includes"])
|
server.addPugDir("pug", ["pug/includes"])
|
||||||
|
server.addRoute("/", "pug/home.pug", "pug")
|
||||||
|
|
||||||
server.addStaticHashTableDir("html/static/js")
|
server.addStaticHashTableDir("html/static/js")
|
||||||
server.addStaticHashTableDir("html/static/js/elemjs")
|
server.addStaticHashTableDir("html/static/js/elemjs")
|
||||||
@ -20,7 +21,3 @@ server.addStaticHashTableDir("html/static/js/elemjs")
|
|||||||
server.addAPIDir("api")
|
server.addAPIDir("api")
|
||||||
|
|
||||||
server.startServer()
|
server.startServer()
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
console.log(server.staticFileTable, server.pageHandlers)
|
|
||||||
}, 2000)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user