diff options
Diffstat (limited to 'web/src/blog.tsx')
| -rw-r--r-- | web/src/blog.tsx | 156 |
1 files changed, 152 insertions, 4 deletions
diff --git a/web/src/blog.tsx b/web/src/blog.tsx index 9d86657..bfef434 100644 --- a/web/src/blog.tsx +++ b/web/src/blog.tsx @@ -1,10 +1,158 @@ import $ from "jquery"; import * as JSX from "./jsx"; -import { Page } from "./components"; -import { AsciiArt } from "./ascii-art"; +import { Page, Spinner } from "./components"; +import { FtpEntry, ftpGetEntries } from "./util"; + +let entries: FtpEntry[] = []; +let reqErr = 0; + +let hljs = null; +let hljs_imported = 0; +async function importHlJs() { + if( hljs ) return; + if( hljs_imported ) return; + + hljs_imported = 1; + hljs = ( await import( 'highlight.js' ) ).default; + + const elements = $( "code" ); + elements.each( ( _, e ) => { + hljs.highlightElement( e ); + } ); +} + +function urlForHref( href: string, isdir: boolean ) { + const url = new URL( window.location.href ); + let path = url.pathname; + if( isdir ) { + if( path.endsWith( '/' ) ) { + return path + href; + } + return path + "/" + href; + } + + const file = href.slice( 0, href.lastIndexOf( "." ) ); + path = path.slice( path.indexOf( '/blog' ) + 5 ); + if( path.endsWith( '/' ) ) + return "/blog" + path + file; + else + return "/blog" + path + "/" + file; +} + +function BlogEntry( props: any ) { + const entry = props.entry as FtpEntry; + return <tr> + <td> + { entry.name == "../" && + <a href='#' onclick={ () => JSX.goUpDirectory() } class="package-entry-link"> + ../ + </a> } + { entry.name != "../" && !entry.isdir && + <a href='#' onclick={ () => JSX.navigate( urlForHref( entry.name, entry.isdir ) ) } class="package-entry-link"> + {entry.name.replace( /_/g, " " )} + </a> } + { entry.name != "../" && entry.isdir && + <a href='#' onclick={ () => JSX.navigate( urlForHref( entry.name, entry.isdir ) ) } class="package-entry-link"> + {entry.name} + </a> } + </td> + <td><span class="package-entry-date">{entry.date} {entry.time}</span></td> + </tr> +} + +function getEndpoint() { + const url = new URL( window.location.href ); + let href = url.pathname.split( "/blog" )[1]; + + if( href[0] == '/' ) { + href = href.slice( 1 ); + } + + return "posts/" + href; +} + +function populateEntries() { + if( reqErr ) { + return JSX.navigate( "/404" ); + } + + if( entries.length <= 0 ) + return setTimeout( populateEntries, 100 ); + + const target = $( "#package-entries" ).find( "table" ); + $( "#package-entries" ).find( ".spinner" ).remove(); + + for( const entry of entries ) { + target.append( <BlogEntry entry={entry} /> ); + } +} + +async function populatePost() { + try { + const res = await fetch( "https://networkheaven.net/" + getEndpoint() + ".html" ); + const text = await res.text(); + if( text.startsWith( "<html>" ) || text.startsWith( "<!doctype html" ) ) { + return populateEntries(); + } + + const titles = text.indexOf( "<title>" ); + const titlee = text.indexOf( "</title>" ); + + if( titles != -1 && titlee != -1 ) { + let title = text.substring( titles + 7, titlee - 1 ); + title = title.replace( /\n/g, "" ); + $( ".page-title h3" )[0].innerText = title; + $( "title" ).html( title ); + } + + importHlJs(); + + $( "#package-entries" ).find( ".spinner" ).remove(); + $( "#package-entries" ).css( "display", "none" ); + $( "#blog-entry" ).html( text ); + $( "#blog-entry" ).css( "display", "flex" ); + $( "#back-btn" ).css( "display", "block" ); + } catch( e ) { + return populateEntries(); + } +} export default function Blog() { - return <Page> - work in progress (: + entries = []; + reqErr = 0; + setTimeout( async () => { + try { + entries = await ftpGetEntries( getEndpoint(), getEndpoint() != 'posts/' ); + } catch( e ) { + reqErr = 1; + } + } ); + + setTimeout( () => { + if( getEndpoint() == 'posts/' ) + return populateEntries(); + + populatePost(); + } ); + + return <Page style="display: flex; flex-direction: column"> + <div class="page-title"> + <h3 style="font-family: JPN24; width: auto" class="gradient">BLOG</h3> + </div> + <hr /> + + <div id="package-entries"> + <table style="width: 90%;" /> + <Spinner /> + </div> + + <div style="display: flex; flex-direction: column width: 100%; justify-content: center; margin-bottom: 26px"> + <div id="blog-entry" style="display: none"> + </div> + </div> + <div style="position: absolute; bottom: 2px; left: calc( 50% - 15px ); display: none" id="back-btn"> + <a href="#" onClick={ () => JSX.goUpDirectory() }>BACK</a> + </div> + </Page> } |
