mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-11-30 11:53:33 +03:00
more homepage
This commit is contained in:
parent
340d8d1436
commit
0805f48dc1
@ -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);
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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">
|
||||||
|
@ -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"
|
|
||||||
>
|
|
||||||
✓
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>Widget size</span>
|
<span>Widget size</span>
|
||||||
|
@ -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 {
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user