Merge pull request #355 from kinode-dao/tm/widget-ui-fixes

Widget ui fixes
This commit is contained in:
0x70b1a5 2024-05-20 22:34:24 -04:00 committed by GitHub
commit 2978bf5935
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 4062 additions and 104 deletions

View File

@ -12,6 +12,9 @@ use std::collections::{BTreeMap, HashMap};
use crate::kinode::process::homepage::{AddRequest, Request as HomepageRequest};
/// Fetching OS version from main package.. LMK if there's a better way...
const CARGO_TOML: &str = include_str!("../../../../Cargo.toml");
#[derive(Serialize, Deserialize)]
struct HomepageApp {
package_name: String,
@ -62,6 +65,7 @@ fn init(our: Address) {
.expect("failed to bind to /our.js");
bind_http_path("/apps", true, false).expect("failed to bind /apps");
bind_http_path("/version", true, false).expect("failed to bind /version");
loop {
let Ok(ref message) = await_message() else {
@ -134,6 +138,13 @@ fn init(our: Address) {
.to_vec(),
);
}
"/version" => {
send_response(
StatusCode::OK,
Some(HashMap::new()),
version_from_cargo_toml().as_bytes().to_vec(),
);
}
_ => {
send_response(
StatusCode::OK,
@ -149,3 +160,18 @@ fn init(our: Address) {
}
}
}
fn version_from_cargo_toml() -> String {
let version = CARGO_TOML
.lines()
.find(|line| line.starts_with("version = "))
.expect("Failed to find version in Cargo.toml");
version
.split('=')
.last()
.expect("Failed to parse version from Cargo.toml")
.trim()
.trim_matches('"')
.to_string()
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -9,8 +9,8 @@
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport"
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" />
<script type="module" crossorigin src="/assets/index-BrbxaEm2.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-iMQiSiXv.css">
<script type="module" crossorigin src="/assets/index-C2uJ-HA5.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C1M4NwvJ.css">
</head>
<body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -9,8 +9,8 @@
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport"
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover" />
<script type="module" crossorigin src="/assets/index-BrbxaEm2.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-iMQiSiXv.css">
<script type="module" crossorigin src="/assets/index-C2uJ-HA5.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C1M4NwvJ.css">
</head>
<body>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,4 +1,3 @@
import { FaCheck, FaX } from "react-icons/fa6"
import useHomepageStore from "../store/homepageStore"
import { Modal } from "./Modal"
import classNames from "classnames"
@ -14,35 +13,47 @@ const WidgetsSettingsModal = () => {
>
<div className="flex-col-center gap-4 mt-4">
{apps.filter(app => app.widget).map(({ label, package_name }) => <div className="flex items-start bg-white/10 rounded p-2 self-stretch">
<h4 className="mr-4">{label}</h4>
<div className="flex-col-center gap-4 grow">
<h4 className="mr-4 grow">{label}</h4>
<div className="flex flex-col gap-4 grow">
<div className="flex-center gap-2">
<span>Show widget</span>
<button
className="icon"
onClick={() => toggleWidgetVisibility(package_name)}
>
{!widgetSettings[package_name]?.hide ? <FaCheck /> : <FaX />}
</button>
<div className="flex relative grow">
<input
type="checkbox"
checked={!widgetSettings[package_name]?.hide}
onChange={() => toggleWidgetVisibility(package_name)}
autoFocus
/>
{!widgetSettings[package_name]?.hide && (
<span
onClick={() => toggleWidgetVisibility(package_name)}
className="checkmark"
>
&#10003;
</span>
)}
</div>
</div>
<div className="flex-center gap-2">
<span>Widget size</span>
<button
className={classNames({
'clear': widgetSettings[package_name]?.size === 'large'
})}
onClick={() => setWidgetSize(package_name, 'small')}
>
Small
</button>
<button
className={classNames({
'clear': widgetSettings[package_name]?.size !== 'large'
})}
onClick={() => setWidgetSize(package_name, 'large')}
>
Large
</button>
<div className="flex-center grow">
<button
className={classNames({
'clear': widgetSettings[package_name]?.size === 'large'
})}
onClick={() => setWidgetSize(package_name, 'small')}
>
Small
</button>
<button
className={classNames({
'clear': widgetSettings[package_name]?.size !== 'large'
})}
onClick={() => setWidgetSize(package_name, 'large')}
>
Large
</button>
</div>
</div>
</div>
</div>)}

View File

@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
import KinodeText from '../components/KinodeText'
import KinodeBird from '../components/KinodeBird'
import useHomepageStore, { HomepageApp } from '../store/homepageStore'
import { FaChevronDown, FaChevronUp, FaScrewdriverWrench, FaV } from 'react-icons/fa6'
import { FaChevronDown, FaChevronUp, FaScrewdriverWrench } from 'react-icons/fa6'
import AppsDock from '../components/AppsDock'
import AllApps from '../components/AllApps'
import Widgets from '../components/Widgets'
@ -10,6 +10,8 @@ import { isMobileCheck } from '../utilities/dimensions'
import classNames from 'classnames'
import WidgetsSettingsModal from '../components/WidgetsSettingsModal'
import valetIcon from '../../public/valet-icon.png'
interface AppStoreApp {
package: string,
publisher: string,
@ -19,6 +21,7 @@ interface AppStoreApp {
}
function Homepage() {
const [our, setOur] = useState('')
const [version, setVersion] = useState('')
const [allAppsExpanded, setAllAppsExpanded] = useState(false)
const { setApps, isHosted, fetchHostedStatus, showWidgetsSettings, setShowWidgetsSettings } = useHomepageStore()
const isMobile = isMobileCheck()
@ -26,9 +29,13 @@ function Homepage() {
const getAppPathsAndIcons = () => {
Promise.all([
fetch('/apps').then(res => res.json() as any as HomepageApp[]),
fetch('/main:app_store:sys/apps').then(res => res.json())
]).then(([appsData, appStoreData]) => {
console.log({ appsData, appStoreData })
fetch('/main:app_store:sys/apps').then(res => res.json()),
fetch('/version').then(res => res.text())
]).then(([appsData, appStoreData, version]) => {
console.log({ appsData, appStoreData, version })
setVersion(version)
const appz = appsData.map(app => ({
...app,
is_favorite: false, // Assuming initial state for all apps
@ -87,13 +94,13 @@ function Homepage() {
'top-8 left-8 right-8': !isMobile,
'top-2 left-2 right-2': isMobile
})}>
{isHosted && <a
href={`https://${our.replace('.os', '')}.hosting.kinode.net/`}
className='button icon'
>
<FaV />
</a>}
{our}
{!isHosted && <img
src={valetIcon}
className='!w-12 !h-12 !p-1 button icon object-cover'
onClick={() => window.location.href = `https://${our.replace('.os', '')}.hosting.kinode.net/`}
/>}
<span>{our}</span>
<span className='bg-white/10 rounded p-1'>v{version}</span>
<button
className="icon ml-auto"
onClick={() => setShowWidgetsSettings(true)}

View File

@ -1372,7 +1372,7 @@ get-stream@^6.0.0:
resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
glob-parent@^5.1.2:
glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
@ -1386,13 +1386,6 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
glob@^7.1.3:
version "7.2.3"
resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz"
@ -1664,21 +1657,7 @@ mimic-fn@^2.1.0:
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
minimatch@^3.0.5:
version "3.1.2"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minimatch@^3.1.1:
version "3.1.2"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minimatch@^3.1.2:
minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==

View File

@ -6,10 +6,6 @@ wit_bindgen::generate!({
world: "process-v0",
});
/// Fetching OS version from main package.. LMK if there's a better way...
const CARGO_TOML: &str = include_str!("../../../../Cargo.toml");
/// A static message to display on the homepage.
const MOTD: &str = "Welcome to Kinode!";
/// 20 minutes
const REFRESH_INTERVAL: u64 = 20 * 60 * 1000;
@ -79,23 +75,20 @@ fn create_widget(posts: Vec<KinodeBlogPost>) -> String {
}}
</style>
</head>
<body class="text-white overflow-hidden">
<p>Kinode {}: {}</p>
<p>Recent posts from kinode.org:</p>
<body class="text-white overflow-hidden h-screen w-screen flex flex-col gap-2">
<div
id="latest-blog-posts"
class="flex flex-col p-2 gap-2 backdrop-brightness-125 rounded-xl shadow-lg h-screen w-screen overflow-y-auto"
class="flex flex-col p-2 gap-2 backdrop-brightness-125 rounded-xl shadow-lg h-screen w-screen overflow-y-auto self-stretch"
style="
scrollbar-color: transparent transparent;
scrollbar-width: none;
"
>
<p class="m-0 self-stretch text-center">Recent Posts</p>
{}
</div>
</body>
</html>"#,
version_from_cargo_toml(),
MOTD,
posts
.into_iter()
.map(post_to_html_string)
@ -103,21 +96,6 @@ fn create_widget(posts: Vec<KinodeBlogPost>) -> String {
);
}
fn version_from_cargo_toml() -> String {
let version = CARGO_TOML
.lines()
.find(|line| line.starts_with("version = "))
.expect("Failed to find version in Cargo.toml");
version
.split('=')
.last()
.expect("Failed to parse version from Cargo.toml")
.trim()
.trim_matches('"')
.to_string()
}
fn fetch_three_most_recent_blog_posts() -> Vec<KinodeBlogPost> {
let blog_posts = match http::send_request_await_response(
http::Method::GET,