mirror of
https://github.com/danbulant/mangui
synced 2026-05-19 03:58:34 +00:00
start working on example application without rusalka
This commit is contained in:
parent
ea298b9dc0
commit
7bc7a6253e
5 changed files with 1640 additions and 7 deletions
19
Cargo.lock
generated
19
Cargo.lock
generated
|
|
@ -841,9 +841,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.3.1"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872"
|
||||
checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crunchy",
|
||||
|
|
@ -1121,14 +1121,21 @@ checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
|
|||
[[package]]
|
||||
name = "mangades"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"mangui",
|
||||
"rusalka",
|
||||
"rusalka-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mangades-plain"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures",
|
||||
"image",
|
||||
"mangui",
|
||||
"reqwest",
|
||||
"rusalka",
|
||||
"rusalka-macro",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
|
|
@ -1993,9 +2000,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.10.0"
|
||||
version = "3.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67"
|
||||
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ members = [
|
|||
"ui",
|
||||
"mangades",
|
||||
"rusalka",
|
||||
"rusalka-macro"
|
||||
"rusalka-macro",
|
||||
"mangades-plain"
|
||||
]
|
||||
1453
mangades-plain/demo/list.json
Normal file
1453
mangades-plain/demo/list.json
Normal file
File diff suppressed because it is too large
Load diff
143
mangades-plain/src/anilist/mod.rs
Normal file
143
mangades-plain/src/anilist/mod.rs
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
use bytes::Bytes;
|
||||
use serde::Deserialize;
|
||||
use mangui::femtovg::ImageFlags;
|
||||
use mangui::nodes::image::ImageLoad;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct GraphqlResponse<T> {
|
||||
data: T
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct MediaListCollectionData {
|
||||
#[serde(rename = "MediaListCollection")]
|
||||
media_list_collection: MediaListCollection
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct MediaListCollection {
|
||||
lists: Vec<MediaList>
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct MediaList {
|
||||
name: String,
|
||||
#[serde(rename = "isCustomList")]
|
||||
is_custom_list: bool,
|
||||
status: String,
|
||||
#[serde(rename = "isSplitCompletedList")]
|
||||
is_split_completed_list: bool,
|
||||
entries: Vec<MediaListEntry>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct MediaListEntry {
|
||||
status: String,
|
||||
progress: i32,
|
||||
#[serde(rename = "progressVolumes")]
|
||||
progress_volumes: i32,
|
||||
repeat: i32,
|
||||
priority: i32,
|
||||
private: bool,
|
||||
notes: Option<String>,
|
||||
score: f32,
|
||||
media: MediaEntry,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct MediaEntry {
|
||||
id: i32,
|
||||
title: MediaTitle,
|
||||
status: String,
|
||||
chapters: Option<i32>,
|
||||
volumes: Option<i32>,
|
||||
#[serde(rename = "coverImage")]
|
||||
cover_image: CoverImage,
|
||||
#[serde(rename = "isAdult")]
|
||||
is_adult: bool,
|
||||
#[serde(rename = "isFavourite")]
|
||||
is_favourite: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct MediaTitle {
|
||||
romaji: String,
|
||||
english: Option<String>,
|
||||
native: String,
|
||||
#[serde(rename = "userPreferred")]
|
||||
user_preferred: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct CoverImage {
|
||||
large: String,
|
||||
medium: String,
|
||||
color: Option<String>,
|
||||
}
|
||||
|
||||
// pub fn load_demo() -> MediaListCollection {
|
||||
// // For demo purposes, load file in demo/list.json
|
||||
// let json = include_str!("../../demo/list.json");
|
||||
// let response: GraphqlResponse<MediaListCollectionData> = serde_json::from_str(json).unwrap();
|
||||
// response.data.media_list_collection
|
||||
// }
|
||||
|
||||
pub async fn load_demo_async() -> MediaListCollection {
|
||||
let json = tokio::fs::read_to_string("demo/list.json").await.unwrap();
|
||||
let response: GraphqlResponse<MediaListCollectionData> = serde_json::from_str(&json).unwrap();
|
||||
response.data.media_list_collection
|
||||
}
|
||||
|
||||
pub async fn load_demo_image(url: String) -> ImageLoad {
|
||||
let last_part = url.split('/').last().unwrap();
|
||||
let path = format!("demo/{}", last_part);
|
||||
let bytes = tokio::fs::read(path).await.unwrap();
|
||||
ImageLoad::LoadVec(bytes, ImageFlags::empty())
|
||||
}
|
||||
|
||||
// pub async fn load_data(appref: Weak<MainWindow>) {
|
||||
// let data = load_demo();
|
||||
|
||||
// let urls = data.lists.iter().flat_map(|list| {
|
||||
// list.entries.iter().map(|entry| {
|
||||
// entry.media.cover_image.medium.clone()
|
||||
// })
|
||||
// }).collect::<Vec<String>>();
|
||||
|
||||
// let mut images = futures::future::join_all(urls.into_iter().map(|url| {
|
||||
// load_image(url)
|
||||
// })).await;
|
||||
// images.reverse();
|
||||
|
||||
// slint::invoke_from_event_loop(move || {
|
||||
// let lists = Rc::new(VecModel::default());
|
||||
|
||||
// for list in data.lists {
|
||||
// let entries: Rc<VecModel<AnilistItem>> = Rc::new(VecModel::default());
|
||||
// for entry in list.entries {
|
||||
// let image = images.pop().unwrap().unwrap();
|
||||
// let image = Image::from_rgba8(image);
|
||||
// let item = AnilistItem {
|
||||
// id: entry.media.id,
|
||||
// title: entry.media.title.user_preferred.into(),
|
||||
// image
|
||||
// };
|
||||
// entries.push(item);
|
||||
// }
|
||||
// let list = AnilistList {
|
||||
// name: list.name.into(),
|
||||
// items: ModelRc::from(entries)
|
||||
// };
|
||||
// lists.push(list);
|
||||
// }
|
||||
// let app = appref.upgrade().unwrap();
|
||||
// app.set_lists(ModelRc::from(lists));
|
||||
// app.set_loading(false);
|
||||
// }).expect("Load data into UI");
|
||||
// }
|
||||
|
||||
async fn load_image(url: String) -> Result<Bytes, reqwest::Error> {
|
||||
let response = reqwest::get(url).await?;
|
||||
let bytes = response.bytes().await?;
|
||||
Ok(bytes)
|
||||
}
|
||||
29
mangades-plain/src/utils.rs
Normal file
29
mangades-plain/src/utils.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
use std::sync::Arc;
|
||||
use mangui::SharedNode;
|
||||
|
||||
pub fn detach(node: &SharedNode) {
|
||||
if let Some(parent) = node.read().unwrap().parent() {
|
||||
parent.write().unwrap().remove_child(node).unwrap();
|
||||
}
|
||||
node.clone().write().unwrap().set_parent(None);
|
||||
}
|
||||
|
||||
pub fn insert(parent: &SharedNode, node: &SharedNode, before: Option<&SharedNode>) {
|
||||
if node.read().unwrap().parent().is_some() && !Arc::ptr_eq(&node.read().unwrap().parent().unwrap(), parent) {
|
||||
detach(node);
|
||||
}
|
||||
match before {
|
||||
Some(before) => {
|
||||
parent.write().unwrap().add_child_before(node.clone(), before).unwrap();
|
||||
node.write().unwrap().set_parent(Some(Arc::downgrade(parent)));
|
||||
},
|
||||
None => {
|
||||
append(parent, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn append(parent: &SharedNode, node: &SharedNode) {
|
||||
parent.write().unwrap().add_child(node.clone()).unwrap();
|
||||
node.write().unwrap().set_parent(Some(Arc::downgrade(parent)));
|
||||
}
|
||||
Loading…
Reference in a new issue