From efb2184245324f9926ce93c82a397c4039b2f92d Mon Sep 17 00:00:00 2001 From: Feror Date: Wed, 12 Mar 2025 09:07:17 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20du=20composant=20Scroll=20et=20d=C3=A9b?= =?UTF-8?q?ut=20de=20la=20page=20About?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front/ScrollComponent.ts | 20 ++++++++++++++++ front/Tabs/About.ts | 52 ++++++++++++++++++++++++++++++++++++++-- front/Tabs/Contact.ts | 2 +- front/Tabs/Projects.ts | 5 ++-- front/Tabs/TabRouter.ts | 7 +++--- front/index.ts | 18 +++++++++----- index.ts | 19 +++++++++++++++ 7 files changed, 109 insertions(+), 14 deletions(-) create mode 100644 front/ScrollComponent.ts diff --git a/front/ScrollComponent.ts b/front/ScrollComponent.ts new file mode 100644 index 0000000..3145170 --- /dev/null +++ b/front/ScrollComponent.ts @@ -0,0 +1,20 @@ +import { newLine } from "."; + +interface ScrollComponentProps { + text: string; + width: number; + height: number; + scrollPosition: number; +} + +const ScrollComponent = ({ text, width, height, scrollPosition }: ScrollComponentProps) => { + const lines = text.split(newLine); + const totalLines = lines.length; + const startLine = scrollPosition; + const endLine = Math.min(startLine + height, totalLines); + + const visibleLines = lines.slice(startLine, endLine); + + return visibleLines.join(newLine); +}; +export default ScrollComponent; diff --git a/front/Tabs/About.ts b/front/Tabs/About.ts index 7787a1a..bd0f430 100644 --- a/front/Tabs/About.ts +++ b/front/Tabs/About.ts @@ -1,9 +1,57 @@ +import { newLine } from ".."; +import ScrollComponent from "../ScrollComponent"; + interface AboutProps { width: number; height: number; + scrollPosition: number; } -const About = ({ width, height }: AboutProps) => { - return "About"; +const age = new Date().getFullYear() - 2004 - (new Date().getMonth() > 10 ? 0 : 1); + +const About = ({ width, height, scrollPosition }: AboutProps) => { + const content = + ` Hi there! My name is Jokin Suares, and I'm a software engineer.${newLine}` + + ` I'm passionate about technology and I love to learn new things.${newLine}` + + ` ${newLine}` + + ` Welcome to my ssh portfolio! Here you can navigate through my projects and contact me.${newLine}` + + ` You might be wondering how this works, right?${newLine}` + + ` Or maybe you're just curious about why anyone would build a portfolio like this.${newLine}` + + ` Well, the answer is simple: I love the terminal!${newLine}` + + ` I spend most of my day in the terminal, so why not have my portfolio there too?${newLine}` + + ` I hope you enjoy it so far!${newLine}` + + ` By the way, you can scroll down to read more about me.${newLine}` + + ` To do so, use the arrow keys on your keyboard.${newLine}` + + ` ${newLine}` + + ` Some background first: ${newLine}` + + ` I'm a ${age} years old French 🇫🇷 software engineer ${newLine}` + + ` I'm always looking for new challenges and opportunities to learn and grow.${newLine}` + + ` At first, I started with backend development, and that was my main focus.${newLine}` + + ` But I quickly diversified my skills and started working on many other things.${newLine}` + + ` ${newLine}` + + ` Here are some of the technologies I've worked with:${newLine}` + + ` - Typescript (Bun, React, React Native, Angular, Svelte, ...)${newLine}` + + ` - Python (Django, Flask, FastAPI, ...)${newLine}` + + ` - Java ${newLine}` + + ` - Docker${newLine}` + + ` - Kubernetes${newLine}` + + ` - Git${newLine}` + + ` - Linux${newLine}` + + ` - Ansible${newLine}` + + ` - Jenkins${newLine}` + + ` - Gitlab CI${newLine}` + + ` - Travis CI${newLine}` + + ` - Circle CI${newLine}` + + ` - ...${newLine}` + + ` ${newLine}` + + ` I am also very passionate about open-source and self-hosting.${newLine}` + + ` This portfolio is hosted on my own hardware, and I'm very proud of that.${newLine}`; + + return ScrollComponent({ + width, + height, + scrollPosition, + text: content, + }); }; export default About; diff --git a/front/Tabs/Contact.ts b/front/Tabs/Contact.ts index b5b1b93..6c31934 100644 --- a/front/Tabs/Contact.ts +++ b/front/Tabs/Contact.ts @@ -14,7 +14,7 @@ const Contact = ({ width, height }: ContactProps) => { ` GitHub: ${link("Feror-BotMaker", "https://github.com/Feror-BotMaker")}${newLine}` + ` Discord: ${link("Feror", "https://discordapp.com/users/323206956640763916")}${newLine}` + ` LinkedIn: ${link("Jokin Suares", "https://www.linkedin.com/in/jokin-suares/")}${newLine}` + - ` ssh: $ ssh contact@jokinsuares.fr${newLine}` + ` ssh: ${link("$ ssh contact@jokinsuares.fr", "ssh:contact@jokinsuares.fr")}${newLine}` ); }; export default Contact; diff --git a/front/Tabs/Projects.ts b/front/Tabs/Projects.ts index 33d42e9..6218c32 100644 --- a/front/Tabs/Projects.ts +++ b/front/Tabs/Projects.ts @@ -1,9 +1,10 @@ interface ProjectsProps { width: number; height: number; + scrollPosition: number; } -const Projects = ({ width, height }: ProjectsProps) => { - return "Projects"; +const Projects = ({ width, height, scrollPosition }: ProjectsProps) => { + return `Projects ${scrollPosition}`; }; export default Projects; diff --git a/front/Tabs/TabRouter.ts b/front/Tabs/TabRouter.ts index dc9fc6f..a2f53be 100644 --- a/front/Tabs/TabRouter.ts +++ b/front/Tabs/TabRouter.ts @@ -6,14 +6,15 @@ interface TabRouterProps { width: number; height: number; selectedTab: "About" | "Projects" | "Contact"; + scrollPosition: number; } -const TabRouter = ({ width, height, selectedTab }: TabRouterProps) => { +const TabRouter = ({ width, height, selectedTab, scrollPosition }: TabRouterProps) => { switch (selectedTab) { case "About": - return About({ width, height }); + return About({ width, height, scrollPosition }); case "Projects": - return Projects({ width, height }); + return Projects({ width, height, scrollPosition }); case "Contact": return Contact({ width, height }); } diff --git a/front/index.ts b/front/index.ts index ce1828b..da8d68d 100644 --- a/front/index.ts +++ b/front/index.ts @@ -6,24 +6,30 @@ interface FrontProps { columns: number; rows: number; selectedTab: "About" | "Projects" | "Contact"; + scrollPosition: number; } +const minimumWidth = 90; +const minimumHeight = 20; + const terminalTooSmall = (width: number, height: number) => { return ( - `Oh no! Your terminal window is too small!${newLine}` + - `Minimum size required: 60x20` + - `Current size: ${width}x${height}` + `\x1b[31mOh no!\x1b[0m Your terminal window is too small!${newLine}` + + `Minimum size required: ${minimumWidth}x${minimumHeight}${newLine}` + + `Current size: ${width >= minimumWidth ? width : `\x1b[31m${width}\x1b[0m`}x${ + height >= minimumHeight ? height : `\x1b[31m${height}\x1b[0m` + }${newLine}` ); }; -const Front = ({ columns, rows, selectedTab }: FrontProps) => { - if (columns < 60 || rows < 20) { +const Front = ({ columns, rows, selectedTab, scrollPosition }: FrontProps) => { + if (columns < minimumWidth || rows < minimumHeight) { return terminalTooSmall(columns, rows); } return ( `${Header({ width: columns, height: 3 })}${newLine}` + `${Categories({ width: columns, height: 3, selectedTab })}${newLine}` + - `${TabRouter({ width: columns, height: 3, selectedTab })}` + `${TabRouter({ width: columns, height: rows - 6, selectedTab, scrollPosition })}` ); }; diff --git a/index.ts b/index.ts index 698695e..ea3e9a2 100644 --- a/index.ts +++ b/index.ts @@ -52,6 +52,7 @@ const server = new Server( columns: number; rows: number; selectedTab: "About" | "Projects" | "Contact"; + scrollPosition: number; stream: ServerChannel | null; contactFormData: { name: string; @@ -63,6 +64,7 @@ const server = new Server( columns: 80, rows: 24, selectedTab: "About", + scrollPosition: 0, stream: null, contactFormData: { name: "", @@ -114,6 +116,7 @@ const server = new Server( stream.on("data", (data: Buffer) => { const cmd = data.toString(); const cmdAsInt = data.readInt8(); + const cmdAsBase64 = data.toBase64(); if ( cmdAsInt == inputCodes.int8.ctrlC || @@ -232,14 +235,30 @@ const server = new Server( switch (cmdAsInt) { case inputCodes.int8.a: userWindow.selectedTab = "About"; + userWindow.scrollPosition = 0; render(); break; case inputCodes.int8.p: userWindow.selectedTab = "Projects"; + userWindow.scrollPosition = 0; render(); break; case inputCodes.int8.c: userWindow.selectedTab = "Contact"; + userWindow.scrollPosition = 0; + render(); + break; + } + switch (cmdAsBase64) { + case inputCodes.base64.arrows.up: + userWindow.scrollPosition -= 1; + if (userWindow.scrollPosition < 0) { + userWindow.scrollPosition = 0; + } + render(); + break; + case inputCodes.base64.arrows.down: + userWindow.scrollPosition += 1; render(); break; }