feat: impl dashboard & issue list

This commit is contained in:
2026-05-06 01:42:38 +08:00
parent bef3a0b9ed
commit 7de0039d38
36 changed files with 2381 additions and 107 deletions

View File

@@ -1,12 +1,12 @@
use gpui::{AppContext, BorrowAppContext};
use std::{any::Any, collections::HashMap, marker::PhantomData, ops::Deref};
use std::{any::Any, borrow::Cow, collections::HashMap, marker::PhantomData, ops::Deref};
pub(crate) trait QueryFn: Clone + 'static {
type Data: 'static;
type Error: std::fmt::Debug + 'static;
type Context: Context;
fn key(&self) -> &'static str;
fn key(&self) -> Key;
async fn run(&self, c: &Self::Context) -> Result<Self::Data, Self::Error>;
}
@@ -17,8 +17,10 @@ pub(crate) trait QueryAppContext: gpui::AppContext {
fn map_result<T, U>(result: Self::Result<T>, f: impl FnOnce(T) -> U) -> Self::Result<U>;
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub(crate) struct Key(Cow<'static, str>);
pub(crate) struct Query {
key: &'static str,
data: QueryData,
}
@@ -193,7 +195,7 @@ pub struct Store<C>
where
C: Context,
{
query_data: HashMap<String, gpui::Entity<Query>>,
query_data: HashMap<Key, gpui::Entity<Query>>,
query_context: C,
}
@@ -217,22 +219,21 @@ where
Q: QueryFn<Context = C>,
CX: QueryAppContext,
{
if let Some(raw) = self.query_data.get(query.key()) {
let query_key = query.key();
if let Some(raw) = self.query_data.get(&query_key) {
return CX::ready(Entity {
raw: raw.clone(),
_marker: PhantomData,
});
}
let key = query.key();
CX::map_result(
cx.new(|_| Query {
key: query.key(),
data: QueryData::Pending,
}),
|raw| {
self.query_data.insert(key.into(), raw.clone());
self.query_data.insert(query_key, raw.clone());
Entity {
raw,
_marker: PhantomData,
@@ -332,15 +333,12 @@ where
E: 'static,
F: QueryFn<Context = C>,
{
let entity = entity.raw.read(cx);
if let Some(entity) = self.query_data.get(entity.key) {
entity.update(cx, |query, cx| {
if !matches!(query.data, QueryData::Loading) {
query.data = QueryData::Stale;
cx.notify()
}
})
}
entity.update(cx, |query, cx| {
if !matches!(query.data, QueryData::Loading) {
query.data = QueryData::Stale;
cx.notify()
}
});
}
}
@@ -374,4 +372,28 @@ impl<'a, E> QueryAppContext for gpui::Context<'a, E> {
}
}
impl AsRef<str> for Key {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl From<&'static str> for Key {
fn from(key: &'static str) -> Self {
Key(Cow::Borrowed(key))
}
}
impl From<String> for Key {
fn from(key: String) -> Self {
Key(Cow::Owned(key))
}
}
impl std::fmt::Display for Key {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl<C> gpui::Global for Store<C> where C: Context + 'static {}