Make mobile nav not require page refresh when JS enabled
Make top bar stick to top of screen Make wide view show rows of 4 Improve notification page styles, text Add button js to more pages
This commit is contained in:
parent
95b3b17c61
commit
5f0682ee22
|
@ -3,16 +3,31 @@
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
picture {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.toolkit-card.nav {
|
.toolkit-card.nav {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.desktop-bar,
|
||||||
|
.mobile-bar {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.mobile-bar {
|
.mobile-bar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-body {
|
.nav-body {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
z-index: 2;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -22,6 +37,13 @@
|
||||||
|
|
||||||
&.nav-open {
|
&.nav-open {
|
||||||
display: block;
|
display: block;
|
||||||
|
animation-duration: 0.3s;
|
||||||
|
animation-name: slideup;
|
||||||
|
}
|
||||||
|
&.nav-closing {
|
||||||
|
display: block;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-name: slidedown;
|
||||||
}
|
}
|
||||||
&.nav-closed {
|
&.nav-closed {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -44,7 +66,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-content {
|
.home-content {
|
||||||
padding: 32px 0;
|
padding: 96px 0 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-box {
|
.profile-box {
|
||||||
|
@ -119,7 +141,7 @@
|
||||||
|
|
||||||
.submission-tiles {
|
.submission-tiles {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||||
|
|
||||||
.submission-icon {
|
.submission-icon {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -128,7 +150,6 @@
|
||||||
|
|
||||||
picture {
|
picture {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,10 +206,38 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.submission-box {
|
.submission-box {
|
||||||
max-height: 70vh;
|
max-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
|
||||||
|
img {
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideup {
|
||||||
|
from {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
bottom: -100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
bottom: 0vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slidedown {
|
||||||
|
from {
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
bottom: 0vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
bottom: -100vh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{error::Error, State};
|
use crate::{error::Error, State};
|
||||||
use activitystreams::base::AnyBase;
|
use activitystreams::base::AnyBase;
|
||||||
use actix_web::{web, HttpResponse, Scope};
|
use actix_web::{web, HttpResponse, Scope};
|
||||||
use hyaenidae_profiles::{apub::ApubIds, Spawner};
|
use hyaenidae_profiles::apub::ApubIds;
|
||||||
use sled::Tree;
|
use sled::Tree;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -54,9 +54,11 @@ async fn shared_inbox(
|
||||||
do_inbox(body.into_inner(), &state).await
|
do_inbox(body.into_inner(), &state).await
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: signature validation, Actor check
|
// TODO: signature validation
|
||||||
async fn do_inbox(any_base: AnyBase, state: &State) -> Result<HttpResponse, Error> {
|
async fn do_inbox(any_base: AnyBase, state: &State) -> Result<HttpResponse, Error> {
|
||||||
state.spawn.process(any_base, vec![]);
|
state
|
||||||
|
.spawn
|
||||||
|
.ingest(any_base, "http://temporary.url".parse().unwrap());
|
||||||
Ok(HttpResponse::Created().finish())
|
Ok(HttpResponse::Created().finish())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ use ructe::Ructe;
|
||||||
fn main() -> ructe::Result<()> {
|
fn main() -> ructe::Result<()> {
|
||||||
let mut ructe = Ructe::from_env()?;
|
let mut ructe = Ructe::from_env()?;
|
||||||
let mut statics = ructe.statics()?;
|
let mut statics = ructe.statics()?;
|
||||||
|
statics.add_files("static")?;
|
||||||
statics.add_sass_file("scss/layout.scss")?;
|
statics.add_sass_file("scss/layout.scss")?;
|
||||||
ructe.compile_templates("templates")?;
|
ructe.compile_templates("templates")?;
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,18 @@ pub(super) fn build(
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(super) struct Spawn(QueueHandle);
|
pub(super) struct Spawn(QueueHandle);
|
||||||
|
|
||||||
|
impl Spawn {
|
||||||
|
pub(crate) fn ingest(&self, any_base: AnyBase, key_owner: Url) {
|
||||||
|
if let Err(e) = self.0.queue(Ingest {
|
||||||
|
any_base,
|
||||||
|
key_owner: Some(key_owner),
|
||||||
|
stack: vec![],
|
||||||
|
}) {
|
||||||
|
log::error!("Failed to queue ingest: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Spawner for Spawn {
|
impl Spawner for Spawn {
|
||||||
fn download_apub(&self, url: Url, stack: Vec<AnyBase>) {
|
fn download_apub(&self, url: Url, stack: Vec<AnyBase>) {
|
||||||
if let Err(e) = self.0.queue(DownloadApub { url, stack }) {
|
if let Err(e) = self.0.queue(DownloadApub { url, stack }) {
|
||||||
|
@ -63,7 +75,11 @@ impl Spawner for Spawn {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&self, any_base: AnyBase, stack: Vec<AnyBase>) {
|
fn process(&self, any_base: AnyBase, stack: Vec<AnyBase>) {
|
||||||
if let Err(e) = self.0.queue(Ingest { any_base, stack }) {
|
if let Err(e) = self.0.queue(Ingest {
|
||||||
|
any_base,
|
||||||
|
key_owner: None,
|
||||||
|
stack,
|
||||||
|
}) {
|
||||||
log::error!("Failed to queue process job: {}", e);
|
log::error!("Failed to queue process job: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,6 +125,7 @@ struct DownloadApub {
|
||||||
#[derive(Clone, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, serde::Deserialize, serde::Serialize)]
|
||||||
struct Ingest {
|
struct Ingest {
|
||||||
any_base: AnyBase,
|
any_base: AnyBase,
|
||||||
|
key_owner: Option<Url>,
|
||||||
stack: Vec<AnyBase>,
|
stack: Vec<AnyBase>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +284,10 @@ impl ActixJob for Ingest {
|
||||||
if self.stack.len() > MAX_INGEST_DEPTH {
|
if self.stack.len() > MAX_INGEST_DEPTH {
|
||||||
return Err(anyhow::anyhow!("Max recursion depth exceded"));
|
return Err(anyhow::anyhow!("Max recursion depth exceded"));
|
||||||
}
|
}
|
||||||
state.profiles.ingest(self.any_base, self.stack).await?;
|
state
|
||||||
|
.profiles
|
||||||
|
.ingest(self.any_base, self.key_owner, self.stack)
|
||||||
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,16 +58,18 @@ async fn main() -> anyhow::Result<()> {
|
||||||
secret_key
|
secret_key
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let domain = config
|
||||||
|
.base_url
|
||||||
|
.domain()
|
||||||
|
.expect("Invalid domain for base url")
|
||||||
|
.to_owned();
|
||||||
|
|
||||||
let accounts_config = hyaenidae_accounts::Config {
|
let accounts_config = hyaenidae_accounts::Config {
|
||||||
toolkit_path: format!(
|
toolkit_path: format!(
|
||||||
"/toolkit/{}",
|
"/toolkit/{}",
|
||||||
hyaenidae_toolkit::templates::statics::toolkit_css.name
|
hyaenidae_toolkit::templates::statics::toolkit_css.name
|
||||||
),
|
),
|
||||||
domain: config
|
domain: domain.clone(),
|
||||||
.base_url
|
|
||||||
.domain()
|
|
||||||
.expect("Invalid domain for base url")
|
|
||||||
.to_owned(),
|
|
||||||
key: secret_key,
|
key: secret_key,
|
||||||
https: false,
|
https: false,
|
||||||
pages: std::sync::Arc::new(accounts::Pages),
|
pages: std::sync::Arc::new(accounts::Pages),
|
||||||
|
@ -81,14 +83,17 @@ async fn main() -> anyhow::Result<()> {
|
||||||
)?;
|
)?;
|
||||||
let accounts_state = hyaenidae_accounts::state(&accounts_config, db.clone())?;
|
let accounts_state = hyaenidae_accounts::state(&accounts_config, db.clone())?;
|
||||||
|
|
||||||
|
let state = State::new(
|
||||||
|
spawner.clone(),
|
||||||
|
config.base_url.clone(),
|
||||||
|
config.pictrs_upstream.clone(),
|
||||||
|
&db.clone(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
state.profiles.create_server_actor(domain).await?;
|
||||||
|
|
||||||
if let Some(user) = config.make_admin {
|
if let Some(user) = config.make_admin {
|
||||||
let user = accounts_state.by_username(user).await?.req()?;
|
let user = accounts_state.by_username(user).await?.req()?;
|
||||||
let state = State::new(
|
|
||||||
spawner.clone(),
|
|
||||||
config.base_url,
|
|
||||||
config.pictrs_upstream,
|
|
||||||
&db.clone(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
state.admin.make_admin(user.id())?;
|
state.admin.make_admin(user.id())?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use crate::{comments::Comment, error::Error, nav::NavState, profiles::Profile, State};
|
use crate::{
|
||||||
|
comments::Comment, error::Error, nav::NavState, profiles::Profile, submissions::Submission,
|
||||||
|
State,
|
||||||
|
};
|
||||||
use actix_web::{web, HttpResponse, Scope};
|
use actix_web::{web, HttpResponse, Scope};
|
||||||
use futures::stream::{FuturesUnordered, StreamExt};
|
use futures::stream::{FuturesUnordered, StreamExt};
|
||||||
use hyaenidae_toolkit::{Button, Link};
|
use hyaenidae_toolkit::{Button, Link};
|
||||||
|
@ -206,20 +209,37 @@ async fn remove_comment_notification(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct CommentView<'a> {
|
pub(crate) struct CommentView<'a> {
|
||||||
|
submission: &'a Submission,
|
||||||
|
parent: Option<&'a Comment>,
|
||||||
comment: &'a Comment,
|
comment: &'a Comment,
|
||||||
author: &'a Profile,
|
author: &'a Profile,
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
|
self_id: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CommentView<'a> {
|
impl<'a> CommentView<'a> {
|
||||||
|
fn comment_reply(&self) -> Option<Uuid> {
|
||||||
|
self.parent.and_then(|c| {
|
||||||
|
if c.profile_id() == self.self_id {
|
||||||
|
Some(c.id())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn submission_path(&self) -> Option<String> {
|
fn submission_path(&self) -> Option<String> {
|
||||||
if self.comment.comment_id().is_none() {
|
if self.comment_reply().is_none() {
|
||||||
Some(format!("/submissions/{}", self.comment.submission_id()))
|
Some(format!("/submissions/{}", self.comment.submission_id()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn submission_title(&self) -> String {
|
||||||
|
self.submission.title()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn submission_link(&self, dark: bool) -> Option<Link> {
|
pub(crate) fn submission_link(&self, dark: bool) -> Option<Link> {
|
||||||
self.submission_path().map(|path| {
|
self.submission_path().map(|path| {
|
||||||
let mut link = Link::new_tab(&path);
|
let mut link = Link::new_tab(&path);
|
||||||
|
@ -229,7 +249,7 @@ impl<'a> CommentView<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reply_to_path(&self) -> Option<String> {
|
fn reply_to_path(&self) -> Option<String> {
|
||||||
if let Some(reply_to_id) = self.comment.comment_id() {
|
if let Some(reply_to_id) = self.comment_reply() {
|
||||||
Some(format!("/comments/{}", reply_to_id))
|
Some(format!("/comments/{}", reply_to_id))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -249,7 +269,7 @@ impl<'a> CommentView<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn view_button(&self, dark: bool) -> Button {
|
pub(crate) fn view_button(&self, dark: bool) -> Button {
|
||||||
let btn = Button::primary("View");
|
let btn = Button::secondary("View");
|
||||||
btn.href(&self.comment_path()).new_tab().dark(dark);
|
btn.href(&self.comment_path()).new_tab().dark(dark);
|
||||||
btn
|
btn
|
||||||
}
|
}
|
||||||
|
@ -259,7 +279,7 @@ impl<'a> CommentView<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn remove_button(&self, dark: bool) -> Button {
|
pub(crate) fn remove_button(&self, dark: bool) -> Button {
|
||||||
let btn = Button::primary_outline("Remove");
|
let btn = Button::secondary("Remove");
|
||||||
btn.form(&self.remove_path()).dark(dark);
|
btn.form(&self.remove_path()).dark(dark);
|
||||||
btn
|
btn
|
||||||
}
|
}
|
||||||
|
@ -282,7 +302,7 @@ pub(crate) struct FollowRequestView<'a> {
|
||||||
|
|
||||||
impl<'a> FollowRequestView<'a> {
|
impl<'a> FollowRequestView<'a> {
|
||||||
pub(crate) fn accept_button(&self, dark: bool) -> Button {
|
pub(crate) fn accept_button(&self, dark: bool) -> Button {
|
||||||
let btn = Button::primary("Accept");
|
let btn = Button::secondary("Accept");
|
||||||
btn.form(&format!(
|
btn.form(&format!(
|
||||||
"/notifications/follow-requests/{}/accept",
|
"/notifications/follow-requests/{}/accept",
|
||||||
self.id
|
self.id
|
||||||
|
@ -292,7 +312,7 @@ impl<'a> FollowRequestView<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn reject_button(&self, dark: bool) -> Button {
|
pub(crate) fn reject_button(&self, dark: bool) -> Button {
|
||||||
let btn = Button::primary_outline("Reject");
|
let btn = Button::secondary("Reject");
|
||||||
btn.form(&format!(
|
btn.form(&format!(
|
||||||
"/notifications/follow-requests/{}/reject",
|
"/notifications/follow-requests/{}/reject",
|
||||||
self.id
|
self.id
|
||||||
|
@ -306,10 +326,12 @@ impl<'a> FollowRequestView<'a> {
|
||||||
pub struct NotificationsView {
|
pub struct NotificationsView {
|
||||||
comment_hm: HashMap<Uuid, Comment>,
|
comment_hm: HashMap<Uuid, Comment>,
|
||||||
profile_hm: HashMap<Uuid, Profile>,
|
profile_hm: HashMap<Uuid, Profile>,
|
||||||
|
submission_hm: HashMap<Uuid, Submission>,
|
||||||
fr_profile_hm: HashMap<Uuid, Uuid>,
|
fr_profile_hm: HashMap<Uuid, Uuid>,
|
||||||
comments: Vec<Uuid>,
|
comments: Vec<Uuid>,
|
||||||
follow_requests: Vec<Uuid>,
|
follow_requests: Vec<Uuid>,
|
||||||
count: u64,
|
count: u64,
|
||||||
|
self_id: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NotificationsView {
|
impl NotificationsView {
|
||||||
|
@ -317,11 +339,16 @@ impl NotificationsView {
|
||||||
self.comments.iter().filter_map(move |comment_id| {
|
self.comments.iter().filter_map(move |comment_id| {
|
||||||
let comment = self.comment_hm.get(comment_id)?;
|
let comment = self.comment_hm.get(comment_id)?;
|
||||||
let author = self.profile_hm.get(&comment.profile_id())?;
|
let author = self.profile_hm.get(&comment.profile_id())?;
|
||||||
|
let submission = self.submission_hm.get(&comment.submission_id())?;
|
||||||
|
let parent = comment.comment_id().and_then(|id| self.comment_hm.get(&id));
|
||||||
|
|
||||||
Some(CommentView {
|
Some(CommentView {
|
||||||
comment,
|
comment,
|
||||||
|
parent,
|
||||||
author,
|
author,
|
||||||
|
submission,
|
||||||
id: *comment_id,
|
id: *comment_id,
|
||||||
|
self_id: self.self_id,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -397,6 +424,7 @@ impl NotificationsView {
|
||||||
|
|
||||||
let comment_store = state.profiles.store.comments.clone();
|
let comment_store = state.profiles.store.comments.clone();
|
||||||
let profile_store = state.profiles.store.profiles.clone();
|
let profile_store = state.profiles.store.profiles.clone();
|
||||||
|
let submission_store = state.profiles.store.submissions.clone();
|
||||||
let file_store = state.profiles.store.files.clone();
|
let file_store = state.profiles.store.files.clone();
|
||||||
let follow_request_store = state.profiles.store.view.follow_requests.clone();
|
let follow_request_store = state.profiles.store.view.follow_requests.clone();
|
||||||
let comment_notifs = state.profiles.store.view.comments.clone();
|
let comment_notifs = state.profiles.store.view.comments.clone();
|
||||||
|
@ -406,10 +434,12 @@ impl NotificationsView {
|
||||||
let mut view = NotificationsView {
|
let mut view = NotificationsView {
|
||||||
comment_hm: HashMap::new(),
|
comment_hm: HashMap::new(),
|
||||||
profile_hm: HashMap::new(),
|
profile_hm: HashMap::new(),
|
||||||
|
submission_hm: HashMap::new(),
|
||||||
fr_profile_hm: HashMap::new(),
|
fr_profile_hm: HashMap::new(),
|
||||||
comments: vec![],
|
comments: vec![],
|
||||||
follow_requests: vec![],
|
follow_requests: vec![],
|
||||||
count,
|
count,
|
||||||
|
self_id: profile_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
for comment_id in comment_notifs.for_profile(profile_id) {
|
for comment_id in comment_notifs.for_profile(profile_id) {
|
||||||
|
@ -422,6 +452,21 @@ impl NotificationsView {
|
||||||
)?;
|
)?;
|
||||||
view.profile_hm.insert(profile.id(), profile);
|
view.profile_hm.insert(profile.id(), profile);
|
||||||
}
|
}
|
||||||
|
if !view.submission_hm.contains_key(&comment.submission_id()) {
|
||||||
|
let submission = Submission::from_stores(
|
||||||
|
comment.submission_id(),
|
||||||
|
&submission_store,
|
||||||
|
&file_store,
|
||||||
|
)?;
|
||||||
|
view.submission_hm.insert(submission.id(), submission);
|
||||||
|
}
|
||||||
|
if let Some(id) = comment.comment_id() {
|
||||||
|
if !view.profile_hm.contains_key(&id) {
|
||||||
|
if let Some(comment) = comment_store.by_id(id)? {
|
||||||
|
view.comment_hm.insert(comment.id(), comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view.comments.push(comment.id());
|
view.comments.push(comment.id());
|
||||||
view.comment_hm.insert(comment.id(), comment);
|
view.comment_hm.insert(comment.id(), comment);
|
||||||
|
|
47
server/static/nav.js
Normal file
47
server/static/nav.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
(function(fn) {
|
||||||
|
if (document.readyState === "complete" || document.readyState === "interactive") {
|
||||||
|
setTimeout(fn, 1);
|
||||||
|
} else {
|
||||||
|
document.addEventListener("DOMContentLoaded", fn);
|
||||||
|
}
|
||||||
|
})(function() {
|
||||||
|
function onClick(nav) {
|
||||||
|
return function _listener(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var containsOpen = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < nav.classList.length; i++) {
|
||||||
|
if (nav.classList[i] == "nav-open") {
|
||||||
|
containsOpen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsOpen) {
|
||||||
|
nav.setAttribute("class", "nav-body nav-closing");
|
||||||
|
setTimeout(function() {
|
||||||
|
nav.setAttribute("class", "nav-body nav-closed");
|
||||||
|
}, 500)
|
||||||
|
} else {
|
||||||
|
nav.setAttribute("class", "nav-body nav-open");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var navs = document.getElementsByClassName("nav-body");
|
||||||
|
var nav = navs[0];
|
||||||
|
if (!nav) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var links = document.getElementsByClassName("nav-link");
|
||||||
|
|
||||||
|
for (var i = 0; i < links.length; i++) {
|
||||||
|
var link = links[i];
|
||||||
|
|
||||||
|
if (!link) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
link.addEventListener("click", onClick(nav));
|
||||||
|
}
|
||||||
|
})
|
4
server/templates/button_js.rs.html
Normal file
4
server/templates/button_js.rs.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@use hyaenidae_toolkit::templates::statics::button_js;
|
||||||
|
|
||||||
|
@()
|
||||||
|
<script src="@crate::toolkit_path(button_js.name)"></script>
|
|
@ -1,3 +1,4 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::templates::layouts::home;
|
@use crate::templates::layouts::home;
|
||||||
@use crate::templates::comments::{nodes, profile_box};
|
@use crate::templates::comments::{nodes, profile_box};
|
||||||
@use crate::comments::CommentView;
|
@use crate::comments::CommentView;
|
||||||
|
@ -11,7 +12,9 @@
|
||||||
@(view: &CommentView, nav_state: &NavState)
|
@(view: &CommentView, nav_state: &NavState)
|
||||||
|
|
||||||
@if let Some((comment, author)) = view.comments.item.comment() {
|
@if let Some((comment, author)) = view.comments.item.comment() {
|
||||||
@:home(&author.name(), comment.body(), nav_state, {}, {
|
@:home(&author.name(), comment.body(), nav_state, {
|
||||||
|
@:button_js()
|
||||||
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
@:card_title({ Comment })
|
@:card_title({ Comment })
|
||||||
@:card_body({
|
@:card_body({
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
@use crate::comments::ReportView;
|
@use crate::comments::ReportView;
|
||||||
@use crate::nav::NavState;
|
@use crate::nav::NavState;
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::templates::layouts::home;
|
@use crate::templates::layouts::home;
|
||||||
@use crate::templates::comments::profile_box;
|
@use crate::templates::comments::profile_box;
|
||||||
@use hyaenidae_toolkit::{templates::button_group, Button};
|
@use hyaenidae_toolkit::{templates::button_group, Button};
|
||||||
|
@ -8,7 +9,9 @@
|
||||||
|
|
||||||
@(view: &ReportView, nav_state: &NavState)
|
@(view: &ReportView, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Report Comment", &format!("Report comment by {}", view.author.name()), nav_state, {}, {
|
@:home("Report Comment", &format!("Report comment by {}", view.author.name()), nav_state, {
|
||||||
|
@:button_js()
|
||||||
|
}, {
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), {
|
@:card(Card::full_width().dark(nav_state.dark()), {
|
||||||
@:card_title({ Report Comment })
|
@:card_title({ Report Comment })
|
||||||
@:card_body({
|
@:card_body({
|
||||||
|
|
5
server/templates/file_js.rs.html
Normal file
5
server/templates/file_js.rs.html
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
@use hyaenidae_toolkit::templates::statics::file_input_js;
|
||||||
|
|
||||||
|
@()
|
||||||
|
<script src="@crate::toolkit_path(file_input_js.name)"></script>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
@use crate::{templates::{layouts::root, nav}, nav::NavState};
|
@use crate::{templates::{layouts::root, nav}, nav::NavState};
|
||||||
|
@use crate::templates::statics::nav_js;
|
||||||
@use hyaenidae_toolkit::templates::{bar, centered};
|
@use hyaenidae_toolkit::templates::{bar, centered};
|
||||||
@use hyaenidae_toolkit::{templates::{card, card_body}, Card};
|
@use hyaenidae_toolkit::{templates::{card, card_body}, Card};
|
||||||
@use hyaenidae_toolkit::{templates::link, Link};
|
@use hyaenidae_toolkit::{templates::link, Link};
|
||||||
|
@ -6,7 +7,10 @@
|
||||||
|
|
||||||
@(title: &str, description: &str, nav_state: &NavState, head: Content, body: Content)
|
@(title: &str, description: &str, nav_state: &NavState, head: Content, body: Content)
|
||||||
|
|
||||||
@:root(title, description, nav_state.dark(), { @:head() }, {
|
@:root(title, description, nav_state.dark(), {
|
||||||
|
<script src="@crate::statics_path(nav_js.name)"></script>
|
||||||
|
@:head()
|
||||||
|
}, {
|
||||||
@:bar(nav_state.dark(), "desktop-bar", {
|
@:bar(nav_state.dark(), "desktop-bar", {
|
||||||
<div>
|
<div>
|
||||||
@:link(&Link::current_tab("/").plain(true).dark(nav_state.dark()), {
|
@:link(&Link::current_tab("/").plain(true).dark(nav_state.dark()), {
|
||||||
|
@ -21,7 +25,7 @@
|
||||||
@:link(&Link::current_tab("/").plain(true).dark(nav_state.dark()), {
|
@:link(&Link::current_tab("/").plain(true).dark(nav_state.dark()), {
|
||||||
<h2>Hyaenidae</h2>
|
<h2>Hyaenidae</h2>
|
||||||
})
|
})
|
||||||
<h3>@:link(&Link::current_tab(nav_state.href()).plain(true).dark(nav_state.dark()), { Nav })</h3>
|
<h3 class="nav-link">@:link(&Link::current_tab(nav_state.href()).plain(true).dark(nav_state.dark()), { Nav })</h3>
|
||||||
})
|
})
|
||||||
<div class="home-content">
|
<div class="home-content">
|
||||||
@:centered(false, {
|
@:centered(false, {
|
||||||
|
@ -29,10 +33,12 @@
|
||||||
})
|
})
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-body @nav_state.class_string()">
|
<div class="nav-body @nav_state.class_string()">
|
||||||
@:link(&Link::current_tab(nav_state.href()).plain(true).dark(nav_state.dark()), {
|
<div class="nav-link nav-background">
|
||||||
<div class="nav-background">
|
@:link(&Link::current_tab(nav_state.href()).plain(true).dark(nav_state.dark()), {
|
||||||
</div>
|
<div class="nav-background">
|
||||||
})
|
</div>
|
||||||
|
})
|
||||||
|
</div>
|
||||||
<nav class="nav-links">
|
<nav class="nav-links">
|
||||||
@:centered(false, {
|
@:centered(false, {
|
||||||
@:card(&Card::full_width().classes(&["nav"]).dark(nav_state.dark()), {
|
@:card(&Card::full_width().classes(&["nav"]).dark(nav_state.dark()), {
|
||||||
|
@ -40,9 +46,11 @@
|
||||||
@:nav(nav_state)
|
@:nav(nav_state)
|
||||||
})
|
})
|
||||||
@:card_body({
|
@:card_body({
|
||||||
@:button_group(&[
|
<div class="nav-link">
|
||||||
Button::primary_outline("Close").href(nav_state.href()).dark(nav_state.dark()),
|
@:button_group(&[
|
||||||
])
|
Button::primary_outline("Close").href(nav_state.href()).dark(nav_state.dark()),
|
||||||
|
])
|
||||||
|
</div>
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
@use crate::nav::NavState;
|
@use crate::nav::NavState;
|
||||||
@use crate::notifications::NotificationsView;
|
@use crate::notifications::NotificationsView;
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::templates::layouts::home;
|
@use crate::templates::layouts::home;
|
||||||
@use crate::templates::submissions::profile_box;
|
@use crate::templates::submissions::profile_box;
|
||||||
@use hyaenidae_toolkit::templates::button_group;
|
@use hyaenidae_toolkit::templates::button_group;
|
||||||
|
@ -8,7 +9,9 @@
|
||||||
|
|
||||||
@(view: &NotificationsView, nav_state: &NavState)
|
@(view: &NotificationsView, nav_state: &NavState)
|
||||||
|
|
||||||
@:home(&format!("Notifications: {}", view.count()), "Notifications on Hyaenidae", nav_state, {}, {
|
@:home(&format!("Notifications: {}", view.count()), "Notifications on Hyaenidae", nav_state, {
|
||||||
|
@:button_js()
|
||||||
|
}, {
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), {
|
@:card(Card::full_width().dark(nav_state.dark()), {
|
||||||
@:card_title({ Clear All })
|
@:card_title({ Clear All })
|
||||||
@:card_body({
|
@:card_body({
|
||||||
|
@ -25,12 +28,13 @@
|
||||||
@:card_title({ Follow Requests })
|
@:card_title({ Follow Requests })
|
||||||
@for fr in view.follow_requests() {
|
@for fr in view.follow_requests() {
|
||||||
@:card_body({
|
@:card_body({
|
||||||
@:profile_box(fr.profile, None, nav_state.dark(), {
|
@:profile_box(fr.profile, None, nav_state.dark(), {})
|
||||||
|
<div class="button-section">
|
||||||
@:button_group(&[
|
@:button_group(&[
|
||||||
&fr.accept_button(nav_state.dark()),
|
&fr.accept_button(nav_state.dark()),
|
||||||
&fr.reject_button(nav_state.dark()),
|
&fr.reject_button(nav_state.dark()),
|
||||||
])
|
])
|
||||||
})
|
</div>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@:card_body({
|
@:card_body({
|
||||||
|
@ -50,8 +54,8 @@
|
||||||
@c.author_name()
|
@c.author_name()
|
||||||
})
|
})
|
||||||
@if let Some(l) = c.submission_link(nav_state.dark()) {
|
@if let Some(l) = c.submission_link(nav_state.dark()) {
|
||||||
commented on your
|
commented on your submission:
|
||||||
@:link(&l, { submission })
|
@:link(&l, { @c.submission_title() })
|
||||||
}
|
}
|
||||||
@if let Some(l) = c.reply_to_link(nav_state.dark()) {
|
@if let Some(l) = c.reply_to_link(nav_state.dark()) {
|
||||||
replied to your
|
replied to your
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
||||||
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input, statics::{button_js, file_input_js}}, Button, Card, FileInput};
|
@use crate::templates::{button_js, file_js};
|
||||||
|
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input}, Button, Card, FileInput};
|
||||||
|
|
||||||
@(banner_input: &FileInput, error: Option<String>, profile: &Profile, nav_state: &NavState)
|
@(banner_input: &FileInput, error: Option<String>, profile: &Profile, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
||||||
<script src="/toolkit/@file_input_js.name"></script>
|
@:button_js()
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:file_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="/profiles/create/banner" enctype="multipart/form-data">
|
<form method="POST" action="/profiles/create/banner" enctype="multipart/form-data">
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
||||||
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, text_input, statics::button_js}, Button, Card, TextInput};
|
@use crate::templates::button_js;
|
||||||
|
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, text_input}, Button, Card, TextInput};
|
||||||
|
|
||||||
@(display_name_input: &TextInput, description_input: &TextInput, profile: &Profile, nav_state: &NavState)
|
@(display_name_input: &TextInput, description_input: &TextInput, profile: &Profile, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:button_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="/profiles/create/bio">
|
<form method="POST" action="/profiles/create/bio">
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
@use crate::{templates::layouts::home, nav::NavState};
|
@use crate::{templates::layouts::home, nav::NavState};
|
||||||
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, text_input, statics::button_js}, Button, Card, TextInput};
|
@use crate::templates::button_js;
|
||||||
|
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, text_input}, Button, Card, TextInput};
|
||||||
|
|
||||||
@(handle_input: &TextInput, nav_state: &NavState)
|
@(handle_input: &TextInput, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:button_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="/profiles/create/handle">
|
<form method="POST" action="/profiles/create/handle">
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
@use crate::templates::{button_js, file_js};
|
||||||
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
||||||
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input, statics::{button_js, file_input_js}}, Button, Card, FileInput};
|
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input}, Button, Card, FileInput};
|
||||||
|
|
||||||
@(icon_input: &FileInput, error: Option<String>, profile: &Profile, nav_state: &NavState)
|
@(icon_input: &FileInput, error: Option<String>, profile: &Profile, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
||||||
<script src="/toolkit/@file_input_js.name"></script>
|
@:button_js()
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:file_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="/profiles/create/icon" enctype="multipart/form-data">
|
<form method="POST" action="/profiles/create/icon" enctype="multipart/form-data">
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
||||||
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, statics::button_js}, Button, Card};
|
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title}, Button, Card};
|
||||||
|
|
||||||
@(require_login: bool, error: Option<String>, profile: &Profile, nav_state: &NavState)
|
@(require_login: bool, error: Option<String>, profile: &Profile, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
@:home("Create Profile", "Create a new profile on Hyaenidae", nav_state, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:button_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="/profiles/create/require-login">
|
<form method="POST" action="/profiles/create/require-login">
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
@use crate::templates::{button_js, file_js};
|
||||||
@use crate::{templates::{layouts::home, profiles::{banner, icon, view}}, nav::NavState, profiles::ProfileState};
|
@use crate::{templates::{layouts::home, profiles::{banner, icon, view}}, nav::NavState, profiles::ProfileState};
|
||||||
@use hyaenidae_toolkit::{templates::{button, button_group, card, card_body, card_title, file_input, text_input, statics::{button_js, file_input_js}}, Button, Card};
|
@use hyaenidae_toolkit::{templates::{button, button_group, card, card_body, card_title, file_input, text_input}, Button, Card};
|
||||||
|
|
||||||
@(state: &ProfileState, nav_state: &NavState)
|
@(state: &ProfileState, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Profile Settings", &format!("{}'s profile", state.profile.name()), nav_state, {
|
@:home("Profile Settings", &format!("{}'s profile", state.profile.name()), nav_state, {
|
||||||
<script src="/toolkit/@file_input_js.name"></script>
|
@:button_js()
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:file_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), { @:view(&state.profile, nav_state.dark()) })
|
@:card(Card::full_width().dark(nav_state.dark()), { @:view(&state.profile, nav_state.dark()) })
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), {
|
@:card(Card::full_width().dark(nav_state.dark()), {
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::Profile};
|
||||||
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, statics::button_js}, Button, Card};
|
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title}, Button, Card};
|
||||||
|
|
||||||
@(profile: &Profile, nav_state: &NavState)
|
@(profile: &Profile, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Delete Profile", &format!("Delete {}", profile.name()), nav_state, {
|
@:home("Delete Profile", &format!("Delete {}", profile.name()), nav_state, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:button_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), { @:view(profile, nav_state.dark()) })
|
@:card(Card::full_width().dark(nav_state.dark()), { @:view(profile, nav_state.dark()) })
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), {
|
@:card(Card::full_width().dark(nav_state.dark()), {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::ReportView};
|
@use crate::{templates::{layouts::home, profiles::view}, nav::NavState, profiles::ReportView};
|
||||||
@use hyaenidae_toolkit::{templates::button_group, Button};
|
@use hyaenidae_toolkit::{templates::button_group, Button};
|
||||||
@use hyaenidae_toolkit::{templates::{card, card_body, card_title}, Card};
|
@use hyaenidae_toolkit::{templates::{card, card_body, card_title}, Card};
|
||||||
|
@ -5,7 +6,9 @@
|
||||||
|
|
||||||
@(rview: &ReportView, nav_state: &NavState)
|
@(rview: &ReportView, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Report Profile", rview.profile.description().unwrap_or(&format!("Report {}'s profile on Hyaenidae", rview.profile.name())), nav_state, {}, {
|
@:home("Report Profile", rview.profile.description().unwrap_or(&format!("Report {}'s profile on Hyaenidae", rview.profile.name())), nav_state, {
|
||||||
|
@:button_js()
|
||||||
|
}, {
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), { @:view(&rview.profile, nav_state.dark()) })
|
@:card(Card::full_width().dark(nav_state.dark()), { @:view(&rview.profile, nav_state.dark()) })
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), {
|
@:card(Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="@rview.profile.report_path()">
|
<form method="POST" action="@rview.profile.report_path()">
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::{templates::layouts::home, nav::NavState};
|
@use crate::{templates::layouts::home, nav::NavState};
|
||||||
@use hyaenidae_accounts::{templates::{update_password, update_username}, UpdatePasswordState, UpdateUsernameState, User};
|
@use hyaenidae_accounts::{templates::{update_password, update_username}, UpdatePasswordState, UpdateUsernameState, User};
|
||||||
@use hyaenidae_toolkit::{templates::{button, card, card_body, card_title, statics::button_js}, Button, Card};
|
@use hyaenidae_toolkit::{templates::{button, card, card_body, card_title}, Button, Card};
|
||||||
|
|
||||||
@(user: &User, uname_state: &UpdateUsernameState, pass_state: &UpdatePasswordState, nav_state: &NavState)
|
@(user: &User, uname_state: &UpdateUsernameState, pass_state: &UpdatePasswordState, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Account Settings", "Update account information", nav_state, {
|
@:home("Account Settings", "Update account information", nav_state, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:button_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(Card::full_width().dark(nav_state.dark()), {
|
@:card(Card::full_width().dark(nav_state.dark()), {
|
||||||
@:card_title({ Current Username: @user.username() })
|
@:card_title({ Current Username: @user.username() })
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::{templates::layouts::home, nav::NavState};
|
@use crate::{templates::layouts::home, nav::NavState};
|
||||||
@use hyaenidae_accounts::{templates::delete_user, DeleteUserState};
|
@use hyaenidae_accounts::{templates::delete_user, DeleteUserState};
|
||||||
@use hyaenidae_toolkit::Card;
|
@use hyaenidae_toolkit::Card;
|
||||||
|
|
||||||
@(state: &DeleteUserState, nav_state: &NavState)
|
@(state: &DeleteUserState, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Delete Account", "Are you sure you want to delete your account?", nav_state, {}, {
|
@:home("Delete Account", "Are you sure you want to delete your account?", nav_state, {
|
||||||
|
@:button_js()
|
||||||
|
}, {
|
||||||
@:delete_user(&Card::full_width().dark(nav_state.dark()), state)
|
@:delete_user(&Card::full_width().dark(nav_state.dark()), state)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::{templates::layouts::home, nav::NavState};
|
@use crate::{templates::layouts::home, nav::NavState};
|
||||||
@use hyaenidae_accounts::{templates::login, LoginState};
|
@use hyaenidae_accounts::{templates::login, LoginState};
|
||||||
@use hyaenidae_toolkit::{templates::statics::button_js, Card};
|
@use hyaenidae_toolkit::Card;
|
||||||
|
|
||||||
@(login_state: &LoginState, nav_state: &NavState)
|
@(login_state: &LoginState, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Login", "Log into Hyaenidae", nav_state, {
|
@:home("Login", "Log into Hyaenidae", nav_state, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:button_js()
|
||||||
}, {
|
}, {
|
||||||
@:login(&Card::full_width().dark(nav_state.dark()), login_state)
|
@:login(&Card::full_width().dark(nav_state.dark()), login_state)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::{templates::layouts::home, nav::NavState};
|
@use crate::{templates::layouts::home, nav::NavState};
|
||||||
@use hyaenidae_accounts::{templates::register, RegisterState};
|
@use hyaenidae_accounts::{templates::register, RegisterState};
|
||||||
@use hyaenidae_toolkit::{templates::statics::button_js, Card};
|
@use hyaenidae_toolkit::Card;
|
||||||
|
|
||||||
@(register_state: &RegisterState, nav_state: &NavState)
|
@(register_state: &RegisterState, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Register", "Register for Hyaenidae", nav_state, {
|
@:home("Register", "Register for Hyaenidae", nav_state, { @:button_js() }, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
|
||||||
}, {
|
|
||||||
@:register(&Card::full_width().dark(nav_state.dark()), register_state)
|
@:register(&Card::full_width().dark(nav_state.dark()), register_state)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
@use crate::templates::{button_js, file_js};
|
||||||
@use crate::{templates::layouts::home, nav::NavState};
|
@use crate::{templates::layouts::home, nav::NavState};
|
||||||
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input, statics::{button_js, file_input_js}}, Button, Card, FileInput};
|
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input}, Button, Card, FileInput};
|
||||||
|
|
||||||
@(file: &FileInput, error: Option<String>, nav_state: &NavState)
|
@(file: &FileInput, error: Option<String>, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Create Submission", "Upload a file", nav_state, {
|
@:home("Create Submission", "Upload a file", nav_state, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:button_js()
|
||||||
<script src="/toolkit/@file_input_js.name"></script>
|
@:file_js()
|
||||||
}, {
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
<form method="POST" action="/submissions/create" enctype="multipart/form-data">
|
<form method="POST" action="/submissions/create" enctype="multipart/form-data">
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::templates::layouts::home;
|
@use crate::templates::layouts::home;
|
||||||
@use crate::templates::comments::nodes;
|
@use crate::templates::comments::nodes;
|
||||||
@use crate::templates::submissions::{image, profile_box};
|
@use crate::templates::submissions::{image, profile_box};
|
||||||
|
@ -9,7 +10,9 @@
|
||||||
|
|
||||||
@(view: &SubmissionView, nav_state: &NavState)
|
@(view: &SubmissionView, nav_state: &NavState)
|
||||||
|
|
||||||
@:home(&view.submission.title(), view.submission.description().unwrap_or(&format!("{} hosted on Hyaenidae", view.submission.title())), nav_state, {}, {
|
@:home(&view.submission.title(), view.submission.description().unwrap_or(&format!("{} hosted on Hyaenidae", view.submission.title())), nav_state, {
|
||||||
|
@:button_js()
|
||||||
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
@:card_title({
|
@:card_title({
|
||||||
@view.submission.title()
|
@view.submission.title()
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
@use crate::templates::button_js;
|
||||||
@use crate::templates::admin::submission_box;
|
@use crate::templates::admin::submission_box;
|
||||||
@use crate::templates::layouts::home;
|
@use crate::templates::layouts::home;
|
||||||
@use crate::{nav::NavState, submissions::ReportView};
|
@use crate::{nav::NavState, submissions::ReportView};
|
||||||
|
@ -7,8 +8,9 @@
|
||||||
|
|
||||||
@(view: &ReportView, nav_state: &NavState)
|
@(view: &ReportView, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Report Submission", view.submission.description().unwrap_or(&format!("Report {}'s
|
@:home("Report Submission", view.submission.description().unwrap_or(&format!("Report {}'s submission on Hyaenidae", view.profile.name())), nav_state, {
|
||||||
submission on Hyaenidae", view.profile.name())), nav_state, {}, {
|
@:button_js()
|
||||||
|
}, {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
@:card_title({
|
@:card_title({
|
||||||
Report @view.submission.title()
|
Report @view.submission.title()
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
@use crate::templates::{button_js, file_js};
|
||||||
@use crate::{templates::{layouts::home, submissions::image}, nav::NavState, submissions::SubmissionState};
|
@use crate::{templates::{layouts::home, submissions::image}, nav::NavState, submissions::SubmissionState};
|
||||||
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input, text_input, statics::{button_js, file_input_js}}, Button, Card};
|
@use hyaenidae_toolkit::{templates::{button_group, card, card_body, card_title, file_input, text_input}, Button, Card};
|
||||||
|
|
||||||
@(state: &SubmissionState, nav_state: &NavState)
|
@(state: &SubmissionState, nav_state: &NavState)
|
||||||
|
|
||||||
@:home("Update Submission", "Update information or images", nav_state, {
|
@:home("Update Submission", "Update information or images", nav_state, {
|
||||||
<script src="/toolkit/@button_js.name"></script>
|
@:button_js()
|
||||||
<script src="/toolkit/@file_input_js.name"></script>
|
@:file_js()
|
||||||
}, {
|
}, {
|
||||||
@if !state.is_published() {
|
@if !state.is_published() {
|
||||||
@:card(&Card::full_width().dark(nav_state.dark()), {
|
@:card(&Card::full_width().dark(nav_state.dark()), {
|
||||||
|
|
Loading…
Reference in a new issue