Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 44425723c6 | |||
| 5caa08e145 | |||
| 44959589f8 |
@@ -7,4 +7,5 @@ div[role="menu"] {
|
|||||||
width: auto;
|
width: auto;
|
||||||
outline: none;
|
outline: none;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,11 +113,11 @@ $mediaItemSize: 300px;
|
|||||||
&.placeholder {
|
&.placeholder {
|
||||||
}
|
}
|
||||||
|
|
||||||
&.nsfw img {
|
&.blur img {
|
||||||
filter: blur(20px);
|
filter: blur(20px);
|
||||||
transition: filter 0.25s ease-out;
|
transition: filter 0.25s ease-out;
|
||||||
}
|
}
|
||||||
&.nsfw:hover img {
|
&.blur:hover img {
|
||||||
filter: blur(0px);
|
filter: blur(0px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,90 +1,112 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use tonic::IntoRequest;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
components::MediaItem,
|
components::{MediaItem, MediaItemPlaceHolder},
|
||||||
rpc::{aoba::PageFilter, get_rpc_client},
|
rpc::{
|
||||||
|
aoba::{MediaModel, PageFilter},
|
||||||
|
get_rpc_client,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Props)]
|
#[derive(PartialEq, Clone, Props)]
|
||||||
pub struct MediaGridProps {
|
pub struct MediaGridProps
|
||||||
pub query: Option<String>,
|
{
|
||||||
|
pub query: Signal<String>,
|
||||||
pub max_page: Signal<i32>,
|
pub max_page: Signal<i32>,
|
||||||
pub total_items: Signal<i32>,
|
pub total_items: Signal<i32>,
|
||||||
#[props(default = Some(1))]
|
pub page: Signal<i32>,
|
||||||
pub page: Option<i32>,
|
pub page_size: Signal<i32>,
|
||||||
#[props(default = Some(100))]
|
|
||||||
pub page_size: Option<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoRequest<PageFilter> for MediaGridProps {
|
|
||||||
fn into_request(self) -> tonic::Request<PageFilter> {
|
|
||||||
let f: PageFilter = self.into();
|
|
||||||
f.into_request()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<PageFilter> for MediaGridProps {
|
|
||||||
fn into(self) -> PageFilter {
|
|
||||||
PageFilter {
|
|
||||||
page: self.page,
|
|
||||||
page_size: self.page_size,
|
|
||||||
query: self.query,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn MediaGrid(mut props: MediaGridProps) -> Element {
|
pub fn MediaGrid(mut props: MediaGridProps) -> Element
|
||||||
|
{
|
||||||
|
let mut error_display = use_signal(|| {
|
||||||
|
rsx! {}
|
||||||
|
});
|
||||||
|
let mut items = use_signal::<Option<Vec<MediaModel>>>(|| None);
|
||||||
let media_result = use_resource(use_reactive!(|(props)| async move {
|
let media_result = use_resource(use_reactive!(|(props)| async move {
|
||||||
|
items.set(None);
|
||||||
let mut client = get_rpc_client();
|
let mut client = get_rpc_client();
|
||||||
let result = client.list_media(props.into_request()).await;
|
let request = PageFilter {
|
||||||
if let Ok(items) = result {
|
page_size: Some(props.page_size.cloned()),
|
||||||
|
page: Some(props.page.cloned()),
|
||||||
|
query: Some(props.query.cloned()),
|
||||||
|
};
|
||||||
|
let result = client.list_media(request).await;
|
||||||
|
if let Ok(items) = result
|
||||||
|
{
|
||||||
let res = items.into_inner();
|
let res = items.into_inner();
|
||||||
|
|
||||||
return Ok(res);
|
return Ok(res);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
let err = result.err().unwrap();
|
let err = result.err().unwrap();
|
||||||
let message = err.message();
|
let message = err.message();
|
||||||
return Err(format!("Failed to load results: {message}"));
|
return Err(format!("Failed to load results: {message}"));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
match media_result.cloned() {
|
use_effect(move || match media_result()
|
||||||
Some(value) => match value {
|
{
|
||||||
Ok(result) => {
|
Some(value) => match value
|
||||||
let pagination = result.pagination.unwrap();
|
{
|
||||||
let total_pages = pagination.total_pages;
|
Ok(result) =>
|
||||||
let total_items = pagination.total_items;
|
{
|
||||||
props.max_page.set(total_pages.max(1));
|
if let Some(pagination) = result.pagination
|
||||||
props.total_items.set(total_items.max(1));
|
{
|
||||||
return rsx! {
|
let total_pages = pagination.total_pages;
|
||||||
div {
|
let total_items = pagination.total_items;
|
||||||
class: "mediaGrid",
|
props.max_page.set(total_pages.max(1));
|
||||||
// oncontextmenu: oncontext,
|
props.total_items.set(total_items.max(1));
|
||||||
{result.items.iter().map(|itm| rsx!{
|
|
||||||
MediaItem {
|
|
||||||
item: itm.clone()
|
|
||||||
}
|
|
||||||
})},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Err(msg) => rsx! {
|
|
||||||
div {
|
|
||||||
class: "mediaGrid",
|
|
||||||
div {
|
|
||||||
"Failed to load results: {msg}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
items.set(Some(result.items));
|
||||||
},
|
error_display.set(rsx! {});
|
||||||
None => rsx! {
|
|
||||||
div{
|
|
||||||
class: "mediaGrid",
|
|
||||||
{(0..50).map(|_| rsx!{
|
|
||||||
MediaItem { }
|
|
||||||
})}
|
|
||||||
}
|
}
|
||||||
|
Err(msg) => error_display.set(rsx! {
|
||||||
|
div{
|
||||||
|
"Failed to load results: {msg}"
|
||||||
|
}
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
|
_ =>
|
||||||
|
{}
|
||||||
|
});
|
||||||
|
|
||||||
|
rsx! {
|
||||||
|
div {
|
||||||
|
class: "mediaGrid",
|
||||||
|
{error_display}
|
||||||
|
{match items(){
|
||||||
|
Some(itms) => rsx!{MediaList { items: itms }},
|
||||||
|
None => rsx!{PlaceholderGrid { count: props.page_size.cloned() as usize }}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn PlaceholderGrid(count: usize) -> Element
|
||||||
|
{
|
||||||
|
rsx! {
|
||||||
|
div{
|
||||||
|
class: "mediaGrid",
|
||||||
|
{(0..count).map(|_| rsx!{
|
||||||
|
MediaItemPlaceHolder { }
|
||||||
|
})}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn MediaList(items: Vec<MediaModel>) -> Element
|
||||||
|
{
|
||||||
|
rsx! {
|
||||||
|
{items.iter().map(|itm| rsx!{
|
||||||
|
MediaItem {
|
||||||
|
item: itm.clone()
|
||||||
|
}
|
||||||
|
})}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ use web_sys::window;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
HOST,
|
HOST,
|
||||||
route::Route,
|
|
||||||
rpc::{
|
rpc::{
|
||||||
aoba::{Id, MediaClass, MediaModel, SetMediaClassRequest},
|
aoba::{Id, MediaModel, SetMediaClassRequest},
|
||||||
get_rpc_client,
|
get_rpc_client,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -15,170 +14,180 @@ use crate::{
|
|||||||
#[derive(PartialEq, Clone, Props)]
|
#[derive(PartialEq, Clone, Props)]
|
||||||
pub struct MediaItemProps
|
pub struct MediaItemProps
|
||||||
{
|
{
|
||||||
pub item: Option<MediaModel>,
|
pub item: MediaModel,
|
||||||
// pub oncontextmenu: Option<EventHandler<Event<MouseData>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn MediaItem(props: MediaItemProps) -> Element
|
pub fn MediaItem(props: MediaItemProps) -> Element
|
||||||
{
|
{
|
||||||
let mut class_signal = use_signal(|| "");
|
let item = props.item;
|
||||||
if let Some(item) = props.item
|
let mtype = item.media_type().as_str_name();
|
||||||
|
let filename = item.file_name;
|
||||||
|
let id = item.id.unwrap().value;
|
||||||
|
let thumb = item.thumb_url;
|
||||||
|
let class = item.class;
|
||||||
|
let mut class_signal = use_signal(|| match class
|
||||||
{
|
{
|
||||||
let mtype = item.media_type().as_str_name();
|
1 => "blur",
|
||||||
let filename = item.file_name;
|
2 => "secret",
|
||||||
let id = item.id.unwrap().value;
|
_ => "",
|
||||||
let thumb = item.thumb_url;
|
});
|
||||||
let class = item.class;
|
let url = item.media_url;
|
||||||
let url = item.media_url;
|
let download = format!("{HOST}{url}");
|
||||||
let download = format!("{HOST}{url}");
|
|
||||||
|
|
||||||
match class
|
// class_signal.set(match class
|
||||||
{
|
// {
|
||||||
1 => class_signal.set("nsfw"),
|
// 1 => "blur",
|
||||||
2 => class_signal.set("secret"),
|
// 2 => "secret",
|
||||||
_ => class_signal.set(""),
|
// _ => "",
|
||||||
};
|
// });
|
||||||
|
|
||||||
return rsx! {
|
return rsx! {
|
||||||
ContextMenu{
|
ContextMenu{
|
||||||
ContextMenuTrigger{
|
ContextMenuTrigger{
|
||||||
a {
|
a {
|
||||||
class: "mediaItem {class_signal()}",
|
class: "mediaItem {class_signal()}",
|
||||||
href: "{HOST}{url}",
|
href: "{HOST}{url}",
|
||||||
target: "_blank",
|
target: "_blank",
|
||||||
"data-id" : id.clone(),
|
"data-id" : id.clone(),
|
||||||
img { src: "{HOST}{thumb}" }
|
img { src: "{HOST}{thumb}" }
|
||||||
span { class: "info",
|
span { class: "info",
|
||||||
span { class: "name", "{filename}" }
|
span { class: "name", "{filename}" }
|
||||||
span { class: "details",
|
span { class: "details",
|
||||||
span { "{mtype}" }
|
span { "{mtype}" }
|
||||||
span { "{item.view_count}" }
|
span { "{item.view_count}" }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
ContextMenuContent{
|
},
|
||||||
ContextMenuItem {
|
ContextMenuContent{
|
||||||
index: 0 as usize,
|
ContextMenuItem {
|
||||||
value: id.clone(),
|
index: 0 as usize,
|
||||||
on_select: move |id: String|{
|
value: id.clone(),
|
||||||
window().expect("Failed to get window")
|
on_select: move |id: String|{
|
||||||
.location().set_href(&format!("/media/{}", id))
|
window().expect("Failed to get window")
|
||||||
.expect("Failed to open Url");
|
.location().set_href(&format!("/media/{}", id))
|
||||||
},
|
.expect("Failed to open Url");
|
||||||
div{
|
|
||||||
class: "contextItem",
|
|
||||||
div{
|
|
||||||
class: "label",
|
|
||||||
"Details"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ContextMenuItem {
|
div{
|
||||||
index: 1 as usize,
|
class: "contextItem",
|
||||||
value: "{download}",
|
|
||||||
on_select: move |url: String|{
|
|
||||||
window().expect("Failed to get window").open_with_url_and_target(&url, "_blank").expect("Failed to open url");
|
|
||||||
},
|
|
||||||
div{
|
div{
|
||||||
class: "contextItem",
|
class: "label",
|
||||||
div{
|
"Details"
|
||||||
class: "label",
|
|
||||||
"Download"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
if class != 0 {
|
|
||||||
rsx!{ContextMenuItem {
|
|
||||||
index: 2 as usize,
|
|
||||||
value: "{id}",
|
|
||||||
on_select: async |id: String|{
|
|
||||||
_ = set_class(id, 0).await;
|
|
||||||
},
|
|
||||||
div{
|
|
||||||
class: "contextItem",
|
|
||||||
div{
|
|
||||||
class: "label",
|
|
||||||
"Mark Standard"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}else{
|
|
||||||
rsx!{}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
},
|
||||||
if class != 1 {
|
ContextMenuItem {
|
||||||
rsx!{ContextMenuItem {
|
index: 1 as usize,
|
||||||
index: 2 as usize,
|
value: "{download}",
|
||||||
value: "{id}",
|
on_select: move |url: String|{
|
||||||
on_select: async |id: String|{
|
window().expect("Failed to get window").open_with_url_and_target(&url, "_blank").expect("Failed to open url");
|
||||||
_ = set_class(id, 1).await;
|
|
||||||
},
|
|
||||||
div{
|
|
||||||
class: "contextItem",
|
|
||||||
div{
|
|
||||||
class: "label",
|
|
||||||
"Mark NSFW"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}else{
|
|
||||||
rsx!{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
if class != 1 {
|
|
||||||
rsx!{ContextMenuItem {
|
|
||||||
index: 2 as usize,
|
|
||||||
value: "{id}",
|
|
||||||
on_select: async |id: String|{
|
|
||||||
_ = set_class(id, 2).await;
|
|
||||||
},
|
|
||||||
div{
|
|
||||||
class: "contextItem",
|
|
||||||
div{
|
|
||||||
class: "label",
|
|
||||||
"Mark Secret"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}else{
|
|
||||||
rsx!{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ContextMenuItem {
|
|
||||||
index: 2 as usize,
|
|
||||||
value: "",
|
|
||||||
div{
|
|
||||||
class: "contextItem",
|
|
||||||
div{
|
|
||||||
class: "label",
|
|
||||||
"Delete"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
div{
|
||||||
|
class: "contextItem",
|
||||||
|
div{
|
||||||
|
class: "label",
|
||||||
|
"Download"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if class_signal() != "" {
|
||||||
|
rsx!{ContextMenuItem {
|
||||||
|
index: 2 as usize,
|
||||||
|
value: "{id}",
|
||||||
|
on_select: move |id: String|{
|
||||||
|
spawn(async move {
|
||||||
|
if let Ok(_) = set_class(id, 0).await{
|
||||||
|
class_signal.set("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
div{
|
||||||
|
class: "contextItem",
|
||||||
|
div{
|
||||||
|
class: "label",
|
||||||
|
"Mark Standard"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}else{rsx!{}}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if class_signal() != "blur" {
|
||||||
|
rsx!{ContextMenuItem {
|
||||||
|
index: 2 as usize,
|
||||||
|
value: "{id}",
|
||||||
|
on_select: move |id: String|{
|
||||||
|
spawn(async move {
|
||||||
|
if let Ok(_) = set_class(id, 1).await{
|
||||||
|
class_signal.set("blur");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
div{
|
||||||
|
class: "contextItem",
|
||||||
|
div{
|
||||||
|
class: "label",
|
||||||
|
"Mark NSFW"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}else{rsx!{}}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if class_signal() != "secret" {
|
||||||
|
rsx!{ContextMenuItem {
|
||||||
|
index: 2 as usize,
|
||||||
|
value: "{id}",
|
||||||
|
on_select: move |id: String|{
|
||||||
|
spawn(async move {
|
||||||
|
if let Ok(_) = set_class(id, 2).await{
|
||||||
|
class_signal.set("secret");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
div{
|
||||||
|
class: "contextItem",
|
||||||
|
div{
|
||||||
|
class: "label",
|
||||||
|
"Mark Secret"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}else{rsx!{}}
|
||||||
|
}
|
||||||
|
ContextMenuItem {
|
||||||
|
index: 2 as usize,
|
||||||
|
value: "",
|
||||||
|
div{
|
||||||
|
class: "contextItem",
|
||||||
|
div{
|
||||||
|
class: "label",
|
||||||
|
"Delete"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn MediaItemPlaceHolder() -> Element
|
||||||
|
{
|
||||||
|
return rsx! {
|
||||||
|
div { class: "mediaItem placeholder",
|
||||||
|
img { },
|
||||||
|
span { class: "info",
|
||||||
|
span { class: "name" }
|
||||||
|
span { class: "details",
|
||||||
|
span { }
|
||||||
|
span { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
};
|
||||||
else
|
|
||||||
{
|
|
||||||
return rsx! {
|
|
||||||
div { class: "mediaItem placeholder",
|
|
||||||
img { },
|
|
||||||
span { class: "info",
|
|
||||||
span { class: "name" }
|
|
||||||
span { class: "details",
|
|
||||||
span { }
|
|
||||||
span { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_class(id: String, class: i32) -> Result<Response<()>, Status>
|
async fn set_class(id: String, class: i32) -> Result<Response<()>, Status>
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ const NAV_CSS: Asset = asset!("/assets/style/nav.scss");
|
|||||||
const NAV_ICON: Asset = asset!("/assets/favicon.ico");
|
const NAV_ICON: Asset = asset!("/assets/favicon.ico");
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Navbar() -> Element {
|
pub fn Navbar() -> Element
|
||||||
|
{
|
||||||
rsx! {
|
rsx! {
|
||||||
document::Link { rel: "stylesheet", href: NAV_CSS }
|
document::Link { rel: "stylesheet", href: NAV_CSS }
|
||||||
nav {
|
nav {
|
||||||
@@ -19,17 +20,19 @@ pub fn Navbar() -> Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn MainNaviagation() -> Element {
|
pub fn MainNaviagation() -> Element
|
||||||
|
{
|
||||||
rsx! {
|
rsx! {
|
||||||
div { class: "mainNav",
|
div { class: "mainNav",
|
||||||
Link { class: "navItem", to: Route::Home { }, "Home" }
|
Link { class: "navItem", to: Route::Home { page: None, q: None }, "Home" }
|
||||||
Link { class: "navItem", to: Route::Settings {}, "Settings" }
|
Link { class: "navItem", to: Route::Settings {}, "Settings" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Branding() -> Element {
|
pub fn Branding() -> Element
|
||||||
|
{
|
||||||
rsx! {
|
rsx! {
|
||||||
div { class: "branding",
|
div { class: "branding",
|
||||||
img { src: NAV_ICON, alt: "Aoba" }
|
img { src: NAV_ICON, alt: "Aoba" }
|
||||||
@@ -38,14 +41,16 @@ pub fn Branding() -> Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Widgets() -> Element {
|
pub fn Widgets() -> Element
|
||||||
|
{
|
||||||
rsx! {
|
rsx! {
|
||||||
div { class: "widgets" }
|
div { class: "widgets" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Utils() -> Element {
|
pub fn Utils() -> Element
|
||||||
|
{
|
||||||
let mut auth_context = use_context::<AuthContext>();
|
let mut auth_context = use_context::<AuthContext>();
|
||||||
let version = APP_VERSION;
|
let version = APP_VERSION;
|
||||||
rsx! {
|
rsx! {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
layouts::MainLayout,
|
layouts::MainLayout,
|
||||||
views::{Home, HomePaged, Media, Settings},
|
views::{Home, Media, Settings},
|
||||||
};
|
};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
@@ -9,10 +9,10 @@ use dioxus::prelude::*;
|
|||||||
pub enum Route {
|
pub enum Route {
|
||||||
#[layout(MainLayout)]
|
#[layout(MainLayout)]
|
||||||
|
|
||||||
#[route("/")]
|
|
||||||
Home { },
|
|
||||||
#[route("/?:page&:q")]
|
#[route("/?:page&:q")]
|
||||||
HomePaged { page: i32, q: String },
|
Home { page: Option<i32>, q: Option<String> },
|
||||||
|
// #[route("/")]
|
||||||
|
// Home { },
|
||||||
#[route("/media/:id")]
|
#[route("/media/:id")]
|
||||||
Media { id: String },
|
Media { id: String },
|
||||||
#[route("/settings")]
|
#[route("/settings")]
|
||||||
|
|||||||
@@ -1,28 +1,29 @@
|
|||||||
use crate::components::{MediaGrid, Pagination, Search};
|
use crate::components::{MediaGrid, Pagination, Search};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
#[component]
|
// #[component]
|
||||||
pub fn Home() -> Element
|
// pub fn Home() -> Element
|
||||||
{
|
// {
|
||||||
let query = use_signal(|| "".to_string());
|
// let query = use_signal(|| "".to_string());
|
||||||
let page = use_signal(|| 1 as i32);
|
// let page = use_signal(|| 1 as i32);
|
||||||
let max_page = use_signal(|| 1 as i32);
|
// let max_page = use_signal(|| 1 as i32);
|
||||||
let item_count = use_signal(|| 0 as i32);
|
// let item_count = use_signal(|| 0 as i32);
|
||||||
rsx! {
|
// rsx! {
|
||||||
div {
|
// div {
|
||||||
class: "stickyTop",
|
// class: "stickyTop",
|
||||||
Search { query, page },
|
// Search { query, page },
|
||||||
Pagination { page, max_page, item_count },
|
// Pagination { page, max_page, item_count },
|
||||||
}
|
// }
|
||||||
MediaGrid { query: query.cloned(), page: page.cloned(), max_page, total_items: item_count }
|
// MediaGrid { query: query.cloned(), page: page.cloned(), max_page, total_items: item_count }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn HomePaged(page: i32, q: String) -> Element
|
pub fn Home(page: Option<i32>, q: Option<String>) -> Element
|
||||||
{
|
{
|
||||||
let query = use_signal(|| q);
|
let query = use_signal(|| q.unwrap_or("".to_string()));
|
||||||
let page = use_signal(|| page);
|
let page = use_signal(|| page.unwrap_or(1));
|
||||||
|
let page_size = use_signal::<i32>(|| 100);
|
||||||
let max_page = use_signal(|| 1 as i32);
|
let max_page = use_signal(|| 1 as i32);
|
||||||
let item_count = use_signal(|| 0 as i32);
|
let item_count = use_signal(|| 0 as i32);
|
||||||
rsx! {
|
rsx! {
|
||||||
@@ -31,6 +32,6 @@ pub fn HomePaged(page: i32, q: String) -> Element
|
|||||||
Search { query, page },
|
Search { query, page },
|
||||||
Pagination { page, max_page, item_count },
|
Pagination { page, max_page, item_count },
|
||||||
}
|
}
|
||||||
MediaGrid { query: query.cloned(), page: page.cloned(), max_page, total_items: item_count }
|
MediaGrid { query: query, page: page, max_page, total_items: item_count, page_size }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,16 +39,16 @@ fn MediaPage(media: MediaModel) -> Element
|
|||||||
{
|
{
|
||||||
let url = media.thumb_url;
|
let url = media.thumb_url;
|
||||||
let id = media.id.expect("Media has no id").value.clone();
|
let id = media.id.expect("Media has no id").value.clone();
|
||||||
let cur_class = match media.class
|
let cur_class = use_signal(|| match media.class
|
||||||
{
|
{
|
||||||
0 => "Standard",
|
0 => "Standard",
|
||||||
1 => "NSFW",
|
1 => "NSFW",
|
||||||
2 => "Secret",
|
2 => "Secret",
|
||||||
_ => "Unkown",
|
_ => "Unkown",
|
||||||
};
|
});
|
||||||
rsx! {
|
rsx! {
|
||||||
img { src: "{HOST}{url}", }
|
img { src: "{HOST}{url}", }
|
||||||
label { "Media Class: {cur_class}" }
|
label { "Media Class: {cur_class()}" }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user