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 | ||||
|     nav.main-nav | ||||
|       a(href="/").link.home CloudTube | ||||
|       form(method="get" action="/search").search-form | ||||
|         input(type="text" placeholder="Search" name="q" autocomplete="off").search | ||||
| 
 | ||||
|     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 | ||||
| 
 | ||||
| include includes/video-list-item.pug | ||||
| 
 | ||||
| block head | ||||
|   title= video.title | ||||
|   script(type="module" src=getStaticURL("html", "/static/js/player.js")) | ||||
| @ -56,13 +58,4 @@ block content | ||||
|       h2.related-header Related videos | ||||
|       each r in video.recommendedVideos | ||||
|         .related-video | ||||
|           - let link = `/watch?v=${r.videoId}` | ||||
|           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 | ||||
|           +video_list_item(r) | ||||
|  | ||||
| @ -18,6 +18,9 @@ input, select, button | ||||
| button | ||||
|   cursor: pointer | ||||
| 
 | ||||
| :focus | ||||
|   outline: none | ||||
| 
 | ||||
| :-moz-focusring | ||||
|   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 "video-list-item.sass" as * | ||||
| 
 | ||||
| .video-page | ||||
|   display: grid | ||||
| @ -44,7 +45,8 @@ | ||||
|     .info-secondary | ||||
|       display: flex | ||||
|       flex-direction: column | ||||
|       align-items: end | ||||
|       align-items: flex-end | ||||
|       text-align: right | ||||
|       margin-top: 6px | ||||
|       margin-left: 6px | ||||
| 
 | ||||
| @ -68,50 +70,4 @@ | ||||
|   font-size: 26px | ||||
| 
 | ||||
| .related-video | ||||
|   display: grid | ||||
|   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 | ||||
|   @include video-list-item | ||||
|  | ||||
| @ -2,6 +2,8 @@ | ||||
| @use "includes/colors.sass" as c | ||||
| @use "sass:selector" | ||||
| @use "includes/video-page.sass" | ||||
| @use "includes/search-page.sass" | ||||
| @use "includes/home-page.sass" | ||||
| 
 | ||||
| @font-face | ||||
|   font-family: "Bariol" | ||||
| @ -52,6 +54,9 @@ | ||||
|   &:active | ||||
|     background-color: c.$bg-dark | ||||
| 
 | ||||
| .base-border-look | ||||
|   @include border-button | ||||
| 
 | ||||
| .border-look | ||||
|   @include border-button | ||||
|   @include button-size | ||||
| @ -78,8 +83,14 @@ | ||||
|     &:focus, &:hover | ||||
|       background-color: c.$bg-accent-x | ||||
| 
 | ||||
|   .search-form | ||||
|     display: flex | ||||
|     flex: 1 | ||||
|     align-items: center | ||||
| 
 | ||||
|     .search | ||||
|       @include button-bg | ||||
|       padding: 10px | ||||
|       flex: 1 | ||||
|       margin: 1px | ||||
| 
 | ||||
|  | ||||
| @ -13,6 +13,7 @@ server.addSassDir("sass", ["sass/includes"]) | ||||
| server.addRoute("/static/css/main.css", "sass/main.sass", "sass") | ||||
| 
 | ||||
| server.addPugDir("pug", ["pug/includes"]) | ||||
| server.addRoute("/", "pug/home.pug", "pug") | ||||
| 
 | ||||
| server.addStaticHashTableDir("html/static/js") | ||||
| server.addStaticHashTableDir("html/static/js/elemjs") | ||||
| @ -20,7 +21,3 @@ server.addStaticHashTableDir("html/static/js/elemjs") | ||||
| server.addAPIDir("api") | ||||
| 
 | ||||
| server.startServer() | ||||
| 
 | ||||
| setTimeout(() => { | ||||
| 	console.log(server.staticFileTable, server.pageHandlers) | ||||
| }, 2000) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user