more homepage

This commit is contained in:
dr-frmr 2024-07-26 18:06:23 +03:00
parent 340d8d1436
commit 0805f48dc1
No known key found for this signature in database
6 changed files with 67 additions and 32 deletions

View File

@ -198,7 +198,7 @@ fn init(our: Address) {
Some(HashMap::new()), Some(HashMap::new()),
vec![], vec![],
); );
return; continue;
}; };
// POST of a list of package names. // POST of a list of package names.
// go through the list and update each app in app_data to have the index of its name in the list as its order // go through the list and update each app in app_data to have the index of its name in the list as its order
@ -208,7 +208,7 @@ fn init(our: Address) {
Some(HashMap::new()), Some(HashMap::new()),
vec![], vec![],
); );
return; continue;
}; };
let Ok(favorite_toggle) = let Ok(favorite_toggle) =
serde_json::from_slice::<(String, u32, bool)>(&body.bytes) serde_json::from_slice::<(String, u32, bool)>(&body.bytes)
@ -218,7 +218,7 @@ fn init(our: Address) {
Some(HashMap::new()), Some(HashMap::new()),
vec![], vec![],
); );
return; continue;
}; };
if let Some(app) = app_data.get_mut(&favorite_toggle.0) { if let Some(app) = app_data.get_mut(&favorite_toggle.0) {
app.order = Some(favorite_toggle.1); app.order = Some(favorite_toggle.1);

View File

@ -10,16 +10,18 @@ const AppDisplay: React.FC<AppDisplayProps> = ({ app }) => {
return <a return <a
id={app?.package_name} id={app?.package_name}
href={app?.path} href={app?.path || undefined}
onMouseEnter={() => setIsHovered(true)} onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)} onMouseLeave={() => setIsHovered(false)}
className="app-display" className="app-display"
title={isHovered ? (app?.label || app?.package_name) : (!app?.path ? "This app does not serve a UI" : undefined)}
> >
{app?.base64_icon {app?.base64_icon
? <img className="app-icon" src={app.base64_icon} /> ? <img className="app-icon" src={app.base64_icon} />
: <img className="app-icon" src='/bird-orange.svg' /> : <img className="app-icon" src='/bird-orange.svg' />
} }
<h6>{app?.label || app?.package_name}</h6> <h6>{app?.label || app?.package_name}</h6>
{isHovered && !app?.path && <p>This app does not serve a UI</p>}
{app?.path && isHovered && <button className="app-fave-button" {app?.path && isHovered && <button className="app-fave-button"
onClick={(e) => { onClick={(e) => {
e.preventDefault() e.preventDefault()
@ -34,4 +36,3 @@ const AppDisplay: React.FC<AppDisplayProps> = ({ app }) => {
} }
export default AppDisplay export default AppDisplay

View File

@ -1,4 +1,5 @@
import { FaX } from "react-icons/fa6" import { FaX } from "react-icons/fa6"
import { useEffect } from 'react';
interface Props extends React.HTMLAttributes<HTMLDivElement> { interface Props extends React.HTMLAttributes<HTMLDivElement> {
title: string title: string
@ -6,6 +7,20 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {
} }
export const Modal: React.FC<Props> = ({ title, onClose, children }) => { export const Modal: React.FC<Props> = ({ title, onClose, children }) => {
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
onClose();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [onClose]);
return ( return (
<div className="modal"> <div className="modal">
<div className="modal-inner"> <div className="modal-inner">

View File

@ -18,23 +18,12 @@ const WidgetsSettingsModal = () => {
<h4>{app.label}</h4> <h4>{app.label}</h4>
<div> <div>
<div> <div>
<span>Show widget</span> <span>Show widget<input
<div> type="checkbox"
<input checked={!widgetSettings[app.id]?.hide}
type="checkbox" onChange={() => toggleWidgetVisibility(app.id)}
checked={!widgetSettings[app.id]?.hide} autoFocus
onChange={() => toggleWidgetVisibility(app.id)} /></span>
autoFocus
/>
{!widgetSettings[app.id]?.hide && (
<span
onClick={() => toggleWidgetVisibility(app.id)}
className="checkmark"
>
&#10003;
</span>
)}
</div>
</div> </div>
<div> <div>
<span>Widget size</span> <span>Widget size</span>

View File

@ -1,9 +1,11 @@
body { body {
width: 100%; width: 90vw;
margin: 0 auto;
} }
#homepage { #homepage {
width: 100%; max-width: 960px;
margin: 0 auto;
} }
header { header {
@ -32,7 +34,7 @@ header h1 {
background-color: #4f000085; background-color: #4f000085;
padding: 10px; padding: 10px;
border-radius: 10px; border-radius: 10px;
max-width: 90%; width: fit-content;
margin: 0 auto; margin: 0 auto;
margin-bottom: 10px; margin-bottom: 10px;
} }
@ -63,6 +65,8 @@ header h1 {
width: 100%; width: 100%;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
gap: 10px; gap: 10px;
} }
@ -72,7 +76,7 @@ header h1 {
text-align: center; text-align: center;
position: relative; position: relative;
max-width: 100%; max-width: 100%;
width: 400px; width: 300px;
height: 400px; height: 400px;
overflow: hidden; overflow: hidden;
} }
@ -93,18 +97,24 @@ header h1 {
} }
footer { footer {
position: absolute; text-align: center;
position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 90vw;
margin: 0 auto;
max-height: 100vh; max-height: 100vh;
max-width: 960px;
} }
#all-apps { #all-apps {
border-top: 1px solid black; border: 1px solid black;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: 10px; gap: 10px;
justify-content: space-evenly;
padding: 10px;
background-color: #4f000085; background-color: #4f000085;
border-radius: 5px 5px 0px 0px;
} }
.app-icon { .app-icon {
@ -119,18 +129,28 @@ footer {
width: 100%; width: 100%;
height: 100%; height: 100%;
text-align: center; text-align: center;
background-color: #000000cc;
display: flex;
justify-content: center;
align-items: center;
} }
.modal-inner { .modal-inner {
background-color: #00000085; width: fit-content;
text-align: center;
background-color: var(--gray);
border-radius: 25px; border-radius: 25px;
border: 1px solid black; border: 1px solid black;
padding: 25px;
margin: auto;
} }
.modal-header { .modal-header {
margin-top: 20vh; text-align: center;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between;
margin-bottom: 2em;
} }
.modal .widget-settings { .modal .widget-settings {

View File

@ -20,7 +20,6 @@ function Homepage() {
]).then(([appsData, version]) => { ]).then(([appsData, version]) => {
setVersion(version) setVersion(version)
setApps(appsData) setApps(appsData)
console.log(appsData)
}); });
} }
@ -38,6 +37,17 @@ function Homepage() {
}) })
}, [our]) }, [our])
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape' && allAppsExpanded) {
setAllAppsExpanded(false);
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [allAppsExpanded]);
return ( return (
<div id="homepage"> <div id="homepage">
<header> <header>