mirror of
				https://git.sr.ht/~cadence/cloudtube
				synced 2025-10-30 11:05:36 +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 | ||||||
|       input(type="text" placeholder="Search" name="q" autocomplete="off").search |       form(method="get" action="/search").search-form | ||||||
|  |         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,11 +83,17 @@ | |||||||
|     &:focus, &:hover |     &:focus, &:hover | ||||||
|       background-color: c.$bg-accent-x |       background-color: c.$bg-accent-x | ||||||
| 
 | 
 | ||||||
|   .search |   .search-form | ||||||
|     @include button-bg |     display: flex | ||||||
|     flex: 1 |     flex: 1 | ||||||
|     margin: 1px |     align-items: center | ||||||
| 
 | 
 | ||||||
|     &:hover, &:focus |     .search | ||||||
|       border: 1px solid c.$edge-grey |       @include button-bg | ||||||
|       margin: 0px |       padding: 10px | ||||||
|  |       flex: 1 | ||||||
|  |       margin: 1px | ||||||
|  | 
 | ||||||
|  |       &:hover, &:focus | ||||||
|  |         border: 1px solid c.$edge-grey | ||||||
|  |         margin: 0px | ||||||
|  | |||||||
| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user