add(backend): "/d" -> "/dashboard"
add(frontend): "/d" -> "/dashboard" add(frontend): sync with dorsal example add(frontend): better accessibility styles add(frontend): "modal" utility functions add(frontend): auth picker instead of error screen add(backend): pages::errors:error401 fix(frontend): markdown paste editor errors chore: bump version (v0.13.1 -> v0.13.2)
This commit is contained in:
parent
bd5f7cac36
commit
e834f2449b
|
@ -3,7 +3,7 @@ name = "bundlrs"
|
|||
authors = ["hkau"]
|
||||
license = "MIT"
|
||||
|
||||
version = "0.13.1"
|
||||
version = "0.13.2"
|
||||
edition = "2021"
|
||||
|
||||
rust-version = "1.75"
|
||||
|
|
|
@ -61,19 +61,15 @@ struct DashboardTemplate {
|
|||
body_embed: String,
|
||||
}
|
||||
|
||||
#[get("/d/atomic")]
|
||||
/// Available at "/d/atomic"
|
||||
#[get("/dashboard/atomic")]
|
||||
/// Available at "/dashboard/atomic"
|
||||
pub async fn dashboard_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let (set_cookie, _, token_user) = base::check_auth_status(req.clone(), data.clone()).await;
|
||||
|
||||
if token_user.is_none() {
|
||||
// you must have an account to use atomic pastes
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use atomic pastes.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// fetch pastes
|
||||
|
@ -103,19 +99,15 @@ You can create an account at: /d/auth/register",
|
|||
);
|
||||
}
|
||||
|
||||
#[get("/d/atomic/new")]
|
||||
/// Available at "/d/atomic/new"
|
||||
#[get("/dashboard/atomic/new")]
|
||||
/// Available at "/dashboard/atomic/new"
|
||||
pub async fn new_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let (set_cookie, _, token_user) = base::check_auth_status(req.clone(), data.clone()).await;
|
||||
|
||||
if token_user.is_none() {
|
||||
// you must have an account to use atomic pastes
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use atomic pastes.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
@ -138,8 +130,8 @@ You can create an account at: /d/auth/register",
|
|||
);
|
||||
}
|
||||
|
||||
#[get("/d/atomic/{id:.*}")]
|
||||
/// Available at "/d/atomic/{id}"
|
||||
#[get("/dashboard/atomic/{id:.*}")]
|
||||
/// Available at "/dashboard/atomic/{id}"
|
||||
pub async fn edit_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::AppData>,
|
||||
|
@ -150,12 +142,9 @@ pub async fn edit_request(
|
|||
|
||||
if token_user.is_none() {
|
||||
// you must have an account to use atomic pastes
|
||||
// we'll likely track bandwidth used by atomic pastes and limit it in the future
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use atomic pastes.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
// we'll likely track requests used by atomic pastes and limit it in the future, similar to Vibrant
|
||||
// ...or just migrate to Vibrant
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// get paste
|
||||
|
|
|
@ -3,6 +3,7 @@ use crate::db::AppData;
|
|||
use super::base;
|
||||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
use askama::Template;
|
||||
use awc::http::StatusCode;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "general/404.html")]
|
||||
|
@ -37,3 +38,37 @@ pub async fn error404(req: HttpRequest, data: web::Data<AppData>) -> HttpRespons
|
|||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "general/401.html")]
|
||||
struct Error401Template {
|
||||
// required fields (super::base)
|
||||
info: String,
|
||||
auth_state: bool,
|
||||
guppy: String,
|
||||
site_name: String,
|
||||
body_embed: String,
|
||||
}
|
||||
|
||||
pub async fn error401(req: HttpRequest, data: web::Data<AppData>) -> HttpResponse {
|
||||
// verify auth status
|
||||
let (set_cookie, _, token_user) = base::check_auth_status(req.clone(), data.clone()).await;
|
||||
|
||||
// ...
|
||||
let base = base::get_base_values(token_user.is_some());
|
||||
return HttpResponse::build(StatusCode::from_u16(401).unwrap())
|
||||
.append_header(("Set-Cookie", set_cookie))
|
||||
.append_header(("Content-Type", "text/html"))
|
||||
.body(
|
||||
Error401Template {
|
||||
// required fields
|
||||
info: base.info,
|
||||
auth_state: base.auth_state,
|
||||
guppy: base.guppy,
|
||||
site_name: base.site_name,
|
||||
body_embed: base.body_embed,
|
||||
}
|
||||
.render()
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,10 @@ pub async fn home_request(
|
|||
.unwrap()
|
||||
.paste
|
||||
.content
|
||||
.replace(r"`", "\\`")
|
||||
.replace("\\", "\\\\")
|
||||
.replace("`", "\\`")
|
||||
.replace("$", "\\$")
|
||||
.replace("/", "\\/")
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
|
@ -190,19 +193,15 @@ pub async fn adstxt() -> impl Responder {
|
|||
.body(std::env::var("ADS_TXT").unwrap_or(String::new()));
|
||||
}
|
||||
|
||||
#[get("/d")]
|
||||
/// Available at "/d"
|
||||
#[get("/dashboard")]
|
||||
/// Available at "/dashboard"
|
||||
pub async fn dashboard_request(req: HttpRequest, data: web::Data<AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let (set_cookie, _, token_user) = base::check_auth_status(req.clone(), data.clone()).await;
|
||||
|
||||
if token_user.is_none() {
|
||||
// you must have an account to use the user dashboard
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use the user dashboard.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
@ -228,8 +227,8 @@ You can create an account at: /d/auth/register",
|
|||
);
|
||||
}
|
||||
|
||||
#[get("/d/inbox")]
|
||||
/// Available at "/d/inbox"
|
||||
#[get("/dashboard/inbox")]
|
||||
/// Available at "/dashboard/inbox"
|
||||
pub async fn inbox_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<AppData>,
|
||||
|
@ -240,11 +239,7 @@ pub async fn inbox_request(
|
|||
|
||||
if token_user.is_none() {
|
||||
// you must have an account to use the user dashboard
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use the user dashboard.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// get inboxes
|
||||
|
|
|
@ -236,7 +236,7 @@ pub async fn paste_view_request(
|
|||
Edit
|
||||
</a>", &paste.custom_url);
|
||||
|
||||
let config_button = format!("<a href=\"/d/settings/paste/{}\" class=\"button round\">
|
||||
let config_button = format!("<a href=\"/dashboard/settings/paste/{}\" class=\"button round\">
|
||||
<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-settings\"><path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></svg>
|
||||
<span class=\"device:desktop\">Config</span>
|
||||
</a>", &paste.custom_url);
|
||||
|
@ -397,8 +397,8 @@ pub async fn atomic_paste_view_request(
|
|||
}
|
||||
}
|
||||
|
||||
#[get("/d/pastes")]
|
||||
/// Available at "/d/pastes"
|
||||
#[get("/dashboard/pastes")]
|
||||
/// Available at "/dashboard/pastes"
|
||||
pub async fn dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::AppData>,
|
||||
|
@ -410,11 +410,7 @@ pub async fn dashboard_request(
|
|||
if token_user.is_none() {
|
||||
// you must have an account to use atomic pastes
|
||||
// we'll likely track bandwidth used by atomic pastes and limit it in the future
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use the paste dashboard.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// fetch pastes
|
||||
|
|
|
@ -31,8 +31,8 @@ struct UserSettingsTemplate {
|
|||
body_embed: String,
|
||||
}
|
||||
|
||||
#[get("/d/settings")]
|
||||
/// Available at "/d/settings"
|
||||
#[get("/dashboard/settings")]
|
||||
/// Available at "/dashboard/settings"
|
||||
pub async fn user_settings_request(req: HttpRequest, data: web::Data<AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let (set_cookie, _, token_user) = base::check_auth_status(req.clone(), data.clone()).await;
|
||||
|
@ -56,8 +56,8 @@ pub async fn user_settings_request(req: HttpRequest, data: web::Data<AppData>) -
|
|||
);
|
||||
}
|
||||
|
||||
#[get("/d/settings/paste/{url:.*}")]
|
||||
/// Available at "/d/settings/paste/{custom_url}"
|
||||
#[get("/dashboard/settings/paste/{url:.*}")]
|
||||
/// Available at "/dashboard/settings/paste/{custom_url}"
|
||||
pub async fn paste_settings_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<AppData>,
|
||||
|
|
|
@ -51,19 +51,15 @@ pub struct UsersQueryProps {
|
|||
pub username: Option<String>,
|
||||
}
|
||||
|
||||
#[get("/d/staff")]
|
||||
/// Available at "/d/staff"
|
||||
#[get("/dashboard/staff")]
|
||||
/// Available at "/dashboard/staff"
|
||||
pub async fn dashboard_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let (set_cookie, _, token_user) = base::check_auth_status(req.clone(), data.clone()).await;
|
||||
|
||||
if token_user.is_none() {
|
||||
// you must have an account to use the staff dashboard
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use the staff dashboard.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// validate role
|
||||
|
@ -96,8 +92,8 @@ You can create an account at: /d/auth/register",
|
|||
);
|
||||
}
|
||||
|
||||
#[get("/d/staff/boards")]
|
||||
/// Available at "/d/staff/boards"
|
||||
#[get("/dashboard/staff/boards")]
|
||||
/// Available at "/dashboard/staff/boards"
|
||||
pub async fn staff_boards_dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::AppData>,
|
||||
|
@ -108,11 +104,7 @@ pub async fn staff_boards_dashboard_request(
|
|||
|
||||
if token_user.is_none() {
|
||||
// you must have an account to use the staff dashboard
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use the staff dashboard.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// validate role
|
||||
|
@ -156,8 +148,8 @@ You can create an account at: /d/auth/register",
|
|||
);
|
||||
}
|
||||
|
||||
#[get("/d/staff/users")]
|
||||
/// Available at "/d/staff/users"
|
||||
#[get("/dashboard/staff/users")]
|
||||
/// Available at "/dashboard/staff/users"
|
||||
pub async fn staff_users_dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::AppData>,
|
||||
|
@ -168,11 +160,7 @@ pub async fn staff_users_dashboard_request(
|
|||
|
||||
if token_user.is_none() {
|
||||
// you must have an account to use the staff dashboard
|
||||
return HttpResponse::NotFound().body(
|
||||
"You must have an account to use the staff dashboard.
|
||||
You can login at: /d/auth/login
|
||||
You can create an account at: /d/auth/register",
|
||||
);
|
||||
return super::errors::error401(req, data).await;
|
||||
}
|
||||
|
||||
// validate role
|
||||
|
|
166
static/style.css
166
static/style.css
|
@ -1,6 +1,10 @@
|
|||
/* https://codeberg.org/hkau/fusion */
|
||||
@import url("./css/fusion.css");
|
||||
|
||||
:root {
|
||||
--roundness: var(--u-02);
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
background: var(--background-surface1);
|
||||
transition: background 0.15s;
|
||||
|
@ -15,7 +19,7 @@
|
|||
|
||||
.tabbar button:not(.full-normal),
|
||||
.tabbar .button:not(.full-normal) {
|
||||
border-radius: var(--u-02) var(--u-02) 0 0;
|
||||
border-radius: var(--roundness) var(--roundness) 0 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
|
@ -60,10 +64,11 @@
|
|||
--primary: hsl(0, 100%, 80%);
|
||||
--primary-low: hsl(0, 100%, 76%);
|
||||
|
||||
--secondary: hsl(41, 100%, 62%);
|
||||
--secondary-low: hsl(41, 100%, 58%);
|
||||
--secondary: hsl(180, 80%, 70%);
|
||||
--secondary-low: hsl(180, 70%, 66%);
|
||||
|
||||
--blue3: hsl(208, 98%, 40%);
|
||||
--blue3a: hsla(208, 98%, 40%, 50%);
|
||||
}
|
||||
|
||||
.dark-theme {
|
||||
|
@ -76,10 +81,11 @@
|
|||
--diff: 0%;
|
||||
|
||||
--blue3: hsl(205, 59%, 64%);
|
||||
--blue3a: hsla(205, 59%, 64%, 50%);
|
||||
}
|
||||
|
||||
*.round {
|
||||
border-radius: var(--u-02) !important;
|
||||
border-radius: var(--roundness) !important;
|
||||
}
|
||||
|
||||
.card.less-padding {
|
||||
|
@ -111,28 +117,60 @@ button.border,
|
|||
box-shadow: 0 0 0 1px var(--background-surface2a);
|
||||
}
|
||||
|
||||
button.bundles-primary,
|
||||
.button.bundles-primary {
|
||||
button:not(.no-shadow):hover,
|
||||
.button:not(.no-shadow):hover {
|
||||
box-shadow: inset 0 0 2px 2px var(--background-surface2a);
|
||||
}
|
||||
|
||||
button.theme\:primary,
|
||||
.button.theme\:primary {
|
||||
background: var(--primary);
|
||||
color: black;
|
||||
}
|
||||
|
||||
button.bundles-primary:hover,
|
||||
.button.bundles-primary:hover {
|
||||
button.theme\:primary:hover,
|
||||
.button.theme\:primary:hover {
|
||||
background: var(--primary-low);
|
||||
}
|
||||
|
||||
button.bundles-secondary,
|
||||
.button.bundles-secondary {
|
||||
button.theme\:secondary,
|
||||
.button.theme\:secondary {
|
||||
background: var(--secondary);
|
||||
color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
button.bundles-secondary:hover,
|
||||
.button.bundles-secondary:hover {
|
||||
button.theme\:secondary:hover,
|
||||
.button.theme\:secondary:hover {
|
||||
background: var(--secondary-low);
|
||||
}
|
||||
|
||||
/* focus */
|
||||
a[href]:not(.button):focus,
|
||||
a[href]:not(.button):active {
|
||||
background: black !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.button.active:not(:active):not(:focus) {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
button:focus,
|
||||
.button:focus,
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
select:focus,
|
||||
button:active,
|
||||
.button:active,
|
||||
input:active,
|
||||
textarea:active,
|
||||
select:active {
|
||||
transition: background 0.1s !important;
|
||||
outline: 2px solid var(--blue3) !important;
|
||||
box-shadow: 0 0 0 5px var(--blue3a) !important;
|
||||
z-index: 2 !important;
|
||||
}
|
||||
|
||||
/* input modifications */
|
||||
button + input,
|
||||
.button + input {
|
||||
|
@ -148,17 +186,17 @@ input + .button {
|
|||
|
||||
/* details */
|
||||
details {
|
||||
border-radius: var(--u-02);
|
||||
border-radius: var(--roundness);
|
||||
}
|
||||
|
||||
details[open] {
|
||||
border-radius: var(--u-02) var(--u-02) 0 0 !important;
|
||||
border-radius: var(--roundness) var(--roundness) 0 0 !important;
|
||||
}
|
||||
|
||||
details summary {
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: var(--u-02) !important;
|
||||
border-radius: var(--roundness) !important;
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
|
@ -182,7 +220,7 @@ details[open] summary {
|
|||
background: var(--background-surface1);
|
||||
box-shadow: none;
|
||||
margin-bottom: 0 !important;
|
||||
border-radius: var(--u-02) var(--u-02) 0 0 !important;
|
||||
border-radius: var(--roundness) var(--roundness) 0 0 !important;
|
||||
}
|
||||
|
||||
details summary + .content {
|
||||
|
@ -213,7 +251,7 @@ select {
|
|||
input.round,
|
||||
textarea.round,
|
||||
select.round {
|
||||
border-radius: var(--u-02) !important;
|
||||
border-radius: var(--roundness) !important;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
|
@ -224,7 +262,7 @@ select:focus {
|
|||
|
||||
/* notes */
|
||||
.mdnote {
|
||||
border-radius: var(--u-02) !important;
|
||||
border-radius: var(--roundness) !important;
|
||||
}
|
||||
|
||||
.mdnote-title {
|
||||
|
@ -238,7 +276,7 @@ select:focus {
|
|||
|
||||
/* chips */
|
||||
.chip.mention {
|
||||
border-radius: var(--u-02);
|
||||
border-radius: var(--roundness);
|
||||
background: var(--background-surface2a);
|
||||
border: solid 1px var(--background-surface2);
|
||||
color: var(--text-color);
|
||||
|
@ -282,7 +320,7 @@ select:focus {
|
|||
--active-color: var(--background-surface2a);
|
||||
padding: 0 var(--u-02);
|
||||
background: var(--hidden-color);
|
||||
border-radius: var(--u-02);
|
||||
border-radius: var(--roundness);
|
||||
color: transparent;
|
||||
transition: all 0.15s;
|
||||
box-shadow: none;
|
||||
|
@ -413,18 +451,6 @@ select:focus {
|
|||
margin: 0 0 2rem 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
#link-header {
|
||||
padding: 0 var(--u-10);
|
||||
}
|
||||
|
||||
.link-list {
|
||||
width: 100%;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
#link-header .link-header-middle {
|
||||
padding: calc(var(--u-10) * 2) 0;
|
||||
}
|
||||
|
@ -440,7 +466,27 @@ select:focus {
|
|||
|
||||
#link-header .link-header-bottom .button.active {
|
||||
background: var(--background-surface);
|
||||
box-shadow: none !important;
|
||||
/* box-shadow: none !important; */
|
||||
}
|
||||
|
||||
#link-header.tall .link-header-middle {
|
||||
padding: calc(var(--u-10) * 4) 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
#link-header {
|
||||
padding: 0 var(--u-10);
|
||||
}
|
||||
|
||||
#link-header.tall .link-header-middle {
|
||||
padding: calc(var(--u-10) * 2) 0;
|
||||
}
|
||||
|
||||
.link-list {
|
||||
width: 100%;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* messages */
|
||||
|
@ -474,27 +520,6 @@ select:focus {
|
|||
user-select: none;
|
||||
}
|
||||
|
||||
/* footer */
|
||||
.__footernav {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.__footernav .item {
|
||||
position: relative;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.__footernav .item::before {
|
||||
content: "·";
|
||||
position: absolute;
|
||||
left: -0.75rem;
|
||||
}
|
||||
|
||||
.__footernav .item:first-child:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* more highlight.js styles */
|
||||
.hljs-tag,
|
||||
.hljs-number {
|
||||
|
@ -512,7 +537,7 @@ select:focus {
|
|||
/* code */
|
||||
pre {
|
||||
padding: var(--u-08);
|
||||
border-radius: var(--u-04);
|
||||
border-radius: var(--roundness);
|
||||
}
|
||||
|
||||
pre,
|
||||
|
@ -542,7 +567,7 @@ pre code {
|
|||
}
|
||||
|
||||
.cm-search * {
|
||||
border-radius: var(--u-02) !important;
|
||||
border-radius: var(--roundness) !important;
|
||||
color: var(--text-color) !important;
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
@ -572,7 +597,7 @@ pre code {
|
|||
/* avatar */
|
||||
.avatar {
|
||||
--size: 50px;
|
||||
border-radius: var(--u-02);
|
||||
border-radius: var(--roundness);
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
}
|
||||
|
@ -592,3 +617,28 @@ table.stripped thead tr th {
|
|||
table.stripped tbody tr td {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
table td:focus-within {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* footer */
|
||||
.footernav {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.footernav .item {
|
||||
position: relative;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.footernav .item::before {
|
||||
content: "·";
|
||||
position: absolute;
|
||||
left: -0.75rem;
|
||||
}
|
||||
|
||||
.footernav .item:first-child:before {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ export function paste_settings(
|
|||
};
|
||||
|
||||
// add button
|
||||
option_render = `<button class="bundles-primary round" onclick="document.getElementById('permissions-modal').showModal();">Edit Permissions</button>`;
|
||||
option_render = `<button class="theme:primary round" onclick="document.getElementById('permissions-modal').showModal();">Edit Permissions</button>`;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
|
|
@ -270,5 +270,18 @@ for (const element of Array.from(
|
|||
)}`;
|
||||
}
|
||||
|
||||
// modal
|
||||
for (const element of Array.from(
|
||||
document.querySelectorAll("[data-dialog]")
|
||||
) as HTMLAnchorElement[]) {
|
||||
const dialog_element: HTMLDialogElement = document.getElementById(
|
||||
element.getAttribute("data-dialog")!
|
||||
) as HTMLDialogElement;
|
||||
|
||||
element.addEventListener("click", () => {
|
||||
dialog_element.showModal();
|
||||
});
|
||||
}
|
||||
|
||||
// default export
|
||||
export default {};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<footer class="flex justify-center align-center flex-column full" {% block footer_stuff %}{% endblock %}>
|
||||
<hr class="small" style="width: 425px; max-width: 100%; margin-top: 1rem;" />
|
||||
|
||||
<div class="__footernav" style="padding: 0; margin: 0;">
|
||||
<div class="footernav" style="padding: 0; margin: 0;">
|
||||
<div class="item">
|
||||
<a href="{{ info }}" class="flex align-center g-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
|
@ -64,7 +64,7 @@
|
|||
</div>
|
||||
{% else %}
|
||||
<div class="item">
|
||||
<a href="/d" class="flex align-center g-4">
|
||||
<a href="/dashboard" class="flex align-center g-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-layout-dashboard">
|
||||
|
@ -101,7 +101,7 @@
|
|||
<div style="position: relative; width: 100%;">
|
||||
<div style="position: absolute; bottom: 8px; right: 0;">
|
||||
<a id="theme_button" href="javascript:window.toggle_theme()" title="Toggle Theme"
|
||||
style="color: var(--text-color-faded);">
|
||||
style="color: var(--text-color-faded); display: block;">
|
||||
<div id="theme-icon-sun">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
|
|
28
templates/general/401.html
Normal file
28
templates/general/401.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
{% extends "../toolbar_base.html" %}
|
||||
{% block title %}Auth Options{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex flex-column g-4">
|
||||
<main class="small flex flex-column g-4 align-center">
|
||||
<h3 class="no-margin">Account Required</h3>
|
||||
|
||||
<div class="card secondary round border flex flex-column g-4" style="width: 25rem; max-width: 100dvw;"
|
||||
id="options">
|
||||
<a href="{{ guppy }}/d/auth/login" class="button full round theme:primary"
|
||||
data-wants-redirect="true">Login</a>
|
||||
<a href="{{ guppy }}/d/auth/register" class="button full round theme:secondary"
|
||||
data-wants-redirect="true">Register</a>
|
||||
</div>
|
||||
|
||||
<div style="width: 25rem; max-width: 100dvw;">
|
||||
<hr />
|
||||
|
||||
<div class="flex justify-center footernav">
|
||||
<span class="item"><a href="/">Homepage</a></span>
|
||||
<span class="item"><a href="https://code.stellular.org/stellular/bundlrs">Source Code</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
{% call super() %}
|
||||
{% endblock %}
|
|
@ -4,18 +4,44 @@
|
|||
{% block main_stuff %}style="overflow: hidden; max-height: 100%;"{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="link-header" style="display: flex;" class="flex-column bg-1">
|
||||
<div id="link-header" style="display: flex;" class="flex-column bg-1 tall">
|
||||
<div class="link-header-top"></div>
|
||||
<div class="link-header-middle flex align-center flex-column g-4">
|
||||
<h1 class="no-margin">404: Not Found</h1>
|
||||
|
||||
<div class="flex g-4 flex-wrap">
|
||||
{% if auth_state == false %}
|
||||
<a href="{{ guppy }}/d/auth/login" class="button green-cta round" data-wants-redirect="true">Login</a>
|
||||
<a href="{{ guppy }}/d/auth/register" class="button green secondary round"
|
||||
data-wants-redirect="true">Register</a>
|
||||
<a href="{{ guppy }}/d/auth/login" class="button theme:primary round" data-wants-redirect="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-log-in">
|
||||
<path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" />
|
||||
<polyline points="10 17 15 12 10 7" />
|
||||
<line x1="15" x2="3" y1="12" y2="12" />
|
||||
</svg>
|
||||
Login
|
||||
</a>
|
||||
<a href="{{ guppy }}/d/auth/register" class="button theme:secondary round" data-wants-redirect="true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-user-plus">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<line x1="19" x2="19" y1="8" y2="14" />
|
||||
<line x1="22" x2="16" y1="11" y2="11" />
|
||||
</svg>
|
||||
Register
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="/d" class="button border round">My Dashboard</a>
|
||||
<a href="/dashboard" class="button theme:primary round">
|
||||
My Dashboard
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-arrow-right">
|
||||
<path d="M5 12h14" />
|
||||
<path d="m12 5 7 7-7 7" />
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d" class="button">Home</a>
|
||||
<a href="/d/pastes" class="button">Pastes</a>
|
||||
<a href="/d/atomic" class="button active">Atomic</a>
|
||||
<a href="/dashboard" class="button">Home</a>
|
||||
<a href="/dashboard/pastes" class="button">Pastes</a>
|
||||
<a href="/dashboard/atomic" class="button active">Atomic</a>
|
||||
<a href="{{ puffer }}/d" class="button">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<div class="flex justify-space-between align-center">
|
||||
<b>Atomic Pastes</b>
|
||||
|
||||
<a class="button bundles-primary round" href="/d/atomic/new">
|
||||
<a class="button theme:primary round" href="/dashboard/atomic/new">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-plus-square">
|
||||
|
@ -37,7 +37,7 @@
|
|||
|
||||
<div class="card round secondary flex g-4 flex-column justify-center" id="pastes_list">
|
||||
{% for p in pastes.iter() %}
|
||||
<a class="button secondary round full justify-start" href="/d/atomic/{{ p.id }}">
|
||||
<a class="button secondary round full justify-start no-shadow" href="/dashboard/atomic/{{ p.id }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-folder-archive">
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d" class="button">Home</a>
|
||||
<a href="/d/pastes" class="button">Pastes</a>
|
||||
<a href="/d/atomic" class="button active">Atomic</a>
|
||||
<a href="/dashboard" class="button">Home</a>
|
||||
<a href="/dashboard/pastes" class="button">Pastes</a>
|
||||
<a href="/dashboard/atomic" class="button active">Atomic</a>
|
||||
<a href="{{ puffer }}/d" class="button">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
<hr />
|
||||
|
||||
<button class="bundles-primary full round">
|
||||
<button class="theme:primary full round">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-plus">
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d" class="button">Home</a>
|
||||
<a href="/d/pastes" class="button">Pastes</a>
|
||||
<a href="/d/atomic" class="button active">Atomic</a>
|
||||
<a href="/dashboard" class="button">Home</a>
|
||||
<a href="/dashboard/pastes" class="button">Pastes</a>
|
||||
<a href="/dashboard/atomic" class="button active">Atomic</a>
|
||||
<a href="{{ puffer }}/d" class="button">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -27,7 +27,7 @@
|
|||
|
||||
<form class="flex justify-center align-center g-4">
|
||||
<input type="text" placeholder="/index.(html|css|js)" name="path" class="round full" minlength="4" />
|
||||
<button class="round bundles-primary" style="min-width: max-content;">Open</button>
|
||||
<button class="round theme:primary" style="min-width: max-content;">Open</button>
|
||||
</form>
|
||||
|
||||
<table class="full stripped">
|
||||
|
@ -44,7 +44,7 @@
|
|||
<td><a href="?path={{ p.path }}">{{ p.path }}</a></td>
|
||||
|
||||
<td class="flex g-4 flex-wrap">
|
||||
<a class="button secondary round" href="?path={{ p.path }}" title="Edit File">
|
||||
<a class="button secondary round no-shadow" href="?path={{ p.path }}" title="Edit File">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-file-pen-line">
|
||||
|
@ -54,7 +54,7 @@
|
|||
</svg>
|
||||
</a>
|
||||
|
||||
<button class="secondary round action:more-modal" data-suffix="{{ custom_url }}{{ p.path }}"
|
||||
<button class="secondary round action:more-modal no-shadow" data-suffix="{{ custom_url }}{{ p.path }}"
|
||||
title="More Options">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
@ -85,7 +85,7 @@
|
|||
<tr>
|
||||
<td>View</td>
|
||||
<td>
|
||||
<a class="button round secondary" target="_blank" href="/{{ custom_url }}">
|
||||
<a class="button round secondary no-shadow" target="_blank" href="/{{ custom_url }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-circle-play">
|
||||
|
@ -100,7 +100,7 @@
|
|||
<tr>
|
||||
<td>Delete</td>
|
||||
<td>
|
||||
<button class="round secondary" id="delete">
|
||||
<button class="round secondary no-shadow" id="delete">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-circle-play">
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d" class="button">Home</a>
|
||||
<a href="/d/pastes" class="button active">Pastes</a>
|
||||
<a href="/d/atomic" class="button">Atomic</a>
|
||||
<a href="/dashboard" class="button">Home</a>
|
||||
<a href="/dashboard/pastes" class="button active">Pastes</a>
|
||||
<a href="/dashboard/atomic" class="button">Atomic</a>
|
||||
<a href="{{ puffer }}/d" class="button">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<div class="flex justify-space-between align-center">
|
||||
<b>Pastes</b>
|
||||
|
||||
<a class="button bundles-primary round" href="/">
|
||||
<a class="button theme:primary round" href="/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-plus-square">
|
||||
|
@ -37,7 +37,7 @@
|
|||
|
||||
<div class="card round secondary flex g-4 flex-column justify-center" id="pastes_list">
|
||||
{% for p in pastes.iter() %}
|
||||
<a class="button secondary round full justify-start" href="/?editing={{ p.custom_url }}">
|
||||
<a class="button secondary round full justify-start no-shadow" href="/?editing={{ p.custom_url }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-file-pen">
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<hr />
|
||||
|
||||
<button class="bundles-primary full round">
|
||||
<button class="theme:primary full round">
|
||||
Continue
|
||||
</button>
|
||||
</form>
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d/staff" class="button active">Home</a>
|
||||
<a href="/d/staff/users" class="button">Users</a>
|
||||
<a href="/d/staff/boards" class="button">Boards</a>
|
||||
<a href="/dashboard/staff" class="button active">Home</a>
|
||||
<a href="/dashboard/staff/users" class="button">Users</a>
|
||||
<a href="/dashboard/staff/boards" class="button">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d/staff" class="button">Home</a>
|
||||
<a href="/d/staff/users" class="button">Users</a>
|
||||
<a href="/d/staff/boards" class="button active">Boards</a>
|
||||
<a href="/dashboard/staff" class="button">Home</a>
|
||||
<a href="/dashboard/staff/users" class="button">Users</a>
|
||||
<a href="/dashboard/staff/boards" class="button active">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
|||
<div class="card round secondary flex g-4 flex-column justify-center" id="boards_list">
|
||||
{% for p in posts.iter() %}
|
||||
{% let post = crate::db::derserialize_post(p.content) %}
|
||||
<a class="button secondary round full justify-start" href="{{ puffer }}/{{ post.board }}/posts/{{ p.id }}">
|
||||
<a class="button secondary round full justify-start no-shadow" href="{{ puffer }}/{{ post.board }}/posts/{{ p.id }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-message-square-text">
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d/staff" class="button">Home</a>
|
||||
<a href="/d/staff/users" class="button active">Users</a>
|
||||
<a href="/d/staff/boards" class="button">Boards</a>
|
||||
<a href="/dashboard/staff" class="button">Home</a>
|
||||
<a href="/dashboard/staff/users" class="button active">Users</a>
|
||||
<a href="/dashboard/staff/boards" class="button">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
|||
<input type="text" name="username" id="username" placeholder="Username" class="round" value="{{ username }}"
|
||||
maxlength="250" style="width: calc(100% - 50px);" />
|
||||
|
||||
<button class="round bundles-primary" style="width: 50px;">Go</button>
|
||||
<button class="round theme:primary" style="width: 50px;">Go</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
<div class="flex full g-4 flex-wrap justify-space-between align-center">
|
||||
<h6 class="no-margin">Banhammer</h6>
|
||||
<button class="round bundles-primary" id="hammer-time"
|
||||
<button class="round theme:primary" id="hammer-time"
|
||||
data-endpoint="/api/auth/users/{{ user.user.username }}/ban">Ban User</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
login
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="/d" class="button full round border justify-start">
|
||||
<a href="/dashboard" class="button full round border justify-start">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-layout-dashboard">
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d" class="button active">Home</a>
|
||||
<a href="/d/pastes" class="button">Pastes</a>
|
||||
<a href="/d/atomic" class="button">Atomic</a>
|
||||
<a href="/dashboard" class="button active">Home</a>
|
||||
<a href="/dashboard/pastes" class="button">Pastes</a>
|
||||
<a href="/dashboard/atomic" class="button">Atomic</a>
|
||||
<a href="{{ puffer }}/d" class="button">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<div class="card secondary round flex justify-space-between align-center g-4">
|
||||
<b>Pastes</b>
|
||||
|
||||
<a class="button bundles-primary round" href="/d/pastes">
|
||||
<a class="button theme:primary round" href="/dashboard/pastes">
|
||||
Go
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
@ -46,7 +46,7 @@
|
|||
<div class="card secondary round flex justify-space-between align-center g-4">
|
||||
<b>Atomic Pastes</b>
|
||||
|
||||
<a class="button bundles-primary round" href="/d/atomic">
|
||||
<a class="button theme:primary round" href="/dashboard/atomic">
|
||||
Go
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
@ -62,7 +62,7 @@
|
|||
<div class="card secondary round flex justify-space-between align-center g-4">
|
||||
<b>Site Settings</b>
|
||||
|
||||
<a class="button bundles-primary round" href="/d/settings">
|
||||
<a class="button theme:primary round" href="/dashboard/settings">
|
||||
Go
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
@ -76,7 +76,7 @@
|
|||
<div class="card secondary round flex justify-space-between align-center g-4">
|
||||
<b>My Boards</b>
|
||||
|
||||
<a class="button bundles-primary round" href="{{ puffer }}/d">
|
||||
<a class="button theme:primary round" href="{{ puffer }}/d">
|
||||
Go
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
@ -90,7 +90,7 @@
|
|||
<div class="card secondary round flex justify-space-between align-center g-4">
|
||||
<b>My Inboxes</b>
|
||||
|
||||
<a class="button bundles-primary round" href="/d/inbox">
|
||||
<a class="button theme:primary round" href="/dashboard/inbox">
|
||||
Go
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
@ -104,7 +104,7 @@
|
|||
<div class="card secondary round flex justify-space-between align-center g-4">
|
||||
<b>My Profile</b>
|
||||
|
||||
<a class="button bundles-primary round" href="{{ guppy }}/{{ user.username }}">
|
||||
<a class="button theme:primary round" href="{{ guppy }}/{{ user.username }}">
|
||||
Go
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
@ -118,7 +118,7 @@
|
|||
<div class="card secondary round flex justify-space-between align-center g-4">
|
||||
<b>Account Settings</b>
|
||||
|
||||
<a class="button bundles-primary round" href="{{ guppy }}/{{ user.username }}/settings">
|
||||
<a class="button theme:primary round" href="{{ guppy }}/{{ user.username }}/settings">
|
||||
Go
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
|
|
@ -1,131 +1,134 @@
|
|||
{% extends "../footer_base.html" %}
|
||||
|
||||
{% block title %}{{ site_name }}{% endblock %}
|
||||
{% block main_stuff %}style="overflow: hidden; max-height: 100%; margin-bottom: 0;"{% endblock %}
|
||||
{% block main_stuff %}style="overflow: hidden; max-height: 100%; height: 100%; margin-bottom: 0; margin-top: 0;
|
||||
padding-top: var(--u-04);" class="flex flex-column align-center"{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="tabbar justify-space-between full">
|
||||
<div class="flex">
|
||||
<button id="editor-open-tab-text">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-notebook-pen">
|
||||
<path d="M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4" />
|
||||
<path d="M2 6h4" />
|
||||
<path d="M2 10h4" />
|
||||
<path d="M2 14h4" />
|
||||
<path d="M2 18h4" />
|
||||
<path d="M18.4 2.6a2.17 2.17 0 0 1 3 3L16 11l-4 1 1-4Z" />
|
||||
</svg>
|
||||
Text
|
||||
</button>
|
||||
|
||||
<button id="editor-open-tab-preview" class="secondary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-paintbrush">
|
||||
<path
|
||||
d="M18.37 2.63 14 7l-1.59-1.59a2 2 0 0 0-2.82 0L8 7l9 9 1.59-1.59a2 2 0 0 0 0-2.82L17 10l4.37-4.37a2.12 2.12 0 1 0-3-3Z" />
|
||||
<path d="M9 8c-2 3-4 3.5-7 4l8 10c2-1 6-5 6-7" />
|
||||
<path d="M14.5 17.5 4.5 15" />
|
||||
</svg>
|
||||
Preview
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="-editor" class="tab-container card secondary round"
|
||||
style="border-top-left-radius: 0px !important; padding: var(--u-10) !important;">
|
||||
<div id="editor-tab-text" class="editor-tab -editor active" style="height: 100%;"></div>
|
||||
<div id="editor-tab-preview" class="editor-tab -editor"></div>
|
||||
</div>
|
||||
|
||||
<form class="flex flex-wrap mobile:justify-center justify-space-between g-4 align-center" id="save-changes">
|
||||
{% if edit_mode == false %}
|
||||
<div class="mobile:justify-center flex g-4 justify-start">
|
||||
<button class="round">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-plus">
|
||||
<path d="M5 12h14" />
|
||||
<path d="M12 5v14" />
|
||||
</svg>
|
||||
Publish
|
||||
</button>
|
||||
|
||||
<a class="button round border" href="javascript:document.getElementById('more-modal').showModal();">
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="mobile:justify-center flex-wrap flex g-4 justify-start">
|
||||
<input class="secondary round" type="text" placeholder="Custom URL" minlength="2" maxlength="500"
|
||||
name="custom_url" id="custom_url" autocomplete="off" />
|
||||
|
||||
<input class="secondary round" type="text" placeholder="Edit Password" minlength="5" name="edit_password" />
|
||||
</div>
|
||||
|
||||
<dialog id="more-modal">
|
||||
<div style="width: 25rem; max-width: 100%;">
|
||||
<h2 class="no-margin full text-center">More Options</h2>
|
||||
|
||||
<hr />
|
||||
|
||||
<details class="full round">
|
||||
<summary>Group Settings</summary>
|
||||
|
||||
<div class="card secondary">
|
||||
<input class="full secondary round" type="text" placeholder="Group Name" minlength="2"
|
||||
maxlength="500" name="group_name" id="group_name" autocomplete="off" />
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="full flex justify-right">
|
||||
<a class="button round red" href="javascript:document.getElementById('more-modal').close();">
|
||||
Close
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
{% else %}
|
||||
<div class="mobile:justify-center flex g-4 justify-start full mobile:flex-column">
|
||||
{% if password_not_needed == false %}
|
||||
<input class="secondary round full" type="text" placeholder="Edit Password" minlength="5"
|
||||
name="edit_password" />
|
||||
{% else %}
|
||||
<input class="secondary round full" type="text" placeholder="Passwordless Enabled" minlength="5"
|
||||
name="edit_password" disabled />
|
||||
{% endif %}
|
||||
|
||||
<input class="secondary round full" type="text" placeholder="New Edit Password (optional)" minlength="5"
|
||||
name="new_edit_password" />
|
||||
|
||||
<input class="secondary round full" type="text" placeholder="New Custom URL (optional)" minlength="2"
|
||||
maxlength="500" name="new_custom_url" id="new_custom_url" autocomplete="off" />
|
||||
</div>
|
||||
|
||||
<div class="flex g-4 justify-space-between full">
|
||||
<div class="flex g-4 justify-start">
|
||||
<button class="green round">
|
||||
Save
|
||||
<div class="flex flex-column full">
|
||||
<div class="tabbar justify-space-between full">
|
||||
<div class="flex">
|
||||
<button id="editor-open-tab-text">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-notebook-pen">
|
||||
<path d="M13.4 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7.4" />
|
||||
<path d="M2 6h4" />
|
||||
<path d="M2 10h4" />
|
||||
<path d="M2 14h4" />
|
||||
<path d="M2 18h4" />
|
||||
<path d="M18.4 2.6a2.17 2.17 0 0 1 3 3L16 11l-4 1 1-4Z" />
|
||||
</svg>
|
||||
Text
|
||||
</button>
|
||||
|
||||
<a href="/{{ editing }}" class="button round">Cancel</a>
|
||||
<button id="editor-open-tab-preview" class="secondary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-paintbrush">
|
||||
<path
|
||||
d="M18.37 2.63 14 7l-1.59-1.59a2 2 0 0 0-2.82 0L8 7l9 9 1.59-1.59a2 2 0 0 0 0-2.82L17 10l4.37-4.37a2.12 2.12 0 1 0-3-3Z" />
|
||||
<path d="M9 8c-2 3-4 3.5-7 4l8 10c2-1 6-5 6-7" />
|
||||
<path d="M14.5 17.5 4.5 15" />
|
||||
</svg>
|
||||
Preview
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="-editor" class="tab-container card secondary round"
|
||||
style="border-top-left-radius: 0px !important; padding: var(--u-10) !important;">
|
||||
<div id="editor-tab-text" class="editor-tab -editor active" style="height: 100%;"></div>
|
||||
<div id="editor-tab-preview" class="editor-tab -editor"></div>
|
||||
</div>
|
||||
|
||||
<form class="flex flex-wrap mobile:justify-center justify-space-between g-4 align-center" id="save-changes">
|
||||
{% if edit_mode == false %}
|
||||
<div class="mobile:justify-center flex g-4 justify-start">
|
||||
<button class="round">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||
class="lucide lucide-plus">
|
||||
<path d="M5 12h14" />
|
||||
<path d="M12 5v14" />
|
||||
</svg>
|
||||
Publish
|
||||
</button>
|
||||
|
||||
<a class="button round border" href="javascript:document.getElementById('more-modal').showModal();">
|
||||
More
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a href="javascript:" id="delete-btn" class="button round red">Delete</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="mobile:justify-center flex-wrap flex g-4 justify-start">
|
||||
<input class="secondary round" type="text" placeholder="Custom URL" minlength="2" maxlength="500"
|
||||
name="custom_url" id="custom_url" autocomplete="off" />
|
||||
|
||||
<script type="text/plain" style="display: none;" id="edit-mode">{{ edit_mode }}</script>
|
||||
<script type="text/plain" style="display: none;" id="editing">{{ editing }}</script>
|
||||
<input class="secondary round" type="text" placeholder="Edit Password" minlength="5" name="edit_password" />
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import CreateEditor from "/static/js/MarkdownEditor.js";
|
||||
CreateEditor("editor-tab-text", `{{ starting_content|safe }}`);
|
||||
</script>
|
||||
<dialog id="more-modal">
|
||||
<div style="width: 25rem; max-width: 100%;">
|
||||
<h2 class="no-margin full text-center">More Options</h2>
|
||||
|
||||
<hr />
|
||||
|
||||
<details class="full round">
|
||||
<summary>Group Settings</summary>
|
||||
|
||||
<div class="card secondary">
|
||||
<input class="full secondary round" type="text" placeholder="Group Name" minlength="2"
|
||||
maxlength="500" name="group_name" id="group_name" autocomplete="off" />
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="full flex justify-right">
|
||||
<a class="button round red" href="javascript:document.getElementById('more-modal').close();">
|
||||
Close
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
{% else %}
|
||||
<div class="mobile:justify-center flex g-4 justify-start full mobile:flex-column">
|
||||
{% if password_not_needed == false %}
|
||||
<input class="secondary round full" type="text" placeholder="Edit Password" minlength="5"
|
||||
name="edit_password" />
|
||||
{% else %}
|
||||
<input class="secondary round full" type="text" placeholder="Passwordless Enabled" minlength="5"
|
||||
name="edit_password" disabled />
|
||||
{% endif %}
|
||||
|
||||
<input class="secondary round full" type="text" placeholder="New Edit Password (optional)" minlength="5"
|
||||
name="new_edit_password" />
|
||||
|
||||
<input class="secondary round full" type="text" placeholder="New Custom URL (optional)" minlength="2"
|
||||
maxlength="500" name="new_custom_url" id="new_custom_url" autocomplete="off" />
|
||||
</div>
|
||||
|
||||
<div class="flex g-4 justify-space-between full">
|
||||
<div class="flex g-4 justify-start">
|
||||
<button class="green round">
|
||||
Save
|
||||
</button>
|
||||
|
||||
<a href="/{{ editing }}" class="button round">Cancel</a>
|
||||
</div>
|
||||
|
||||
<a href="javascript:" id="delete-btn" class="button round red">Delete</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
|
||||
<script type="text/plain" style="display: none;" id="edit-mode">{{ edit_mode }}</script>
|
||||
<script type="text/plain" style="display: none;" id="editing">{{ editing }}</script>
|
||||
|
||||
<script type="module">
|
||||
import CreateEditor from "/static/js/MarkdownEditor.js";
|
||||
CreateEditor("editor-tab-text", `{{ starting_content|safe }}`);
|
||||
</script>
|
||||
</div>
|
||||
{% call super() %}
|
||||
{% endblock %}
|
|
@ -12,9 +12,9 @@
|
|||
</div>
|
||||
|
||||
<div class="link-header-bottom">
|
||||
<a href="/d" class="button">Home</a>
|
||||
<a href="/d/pastes" class="button">Pastes</a>
|
||||
<a href="/d/atomic" class="button">Atomic</a>
|
||||
<a href="/dashboard" class="button">Home</a>
|
||||
<a href="/dashboard/pastes" class="button">Pastes</a>
|
||||
<a href="/dashboard/atomic" class="button">Atomic</a>
|
||||
<a href="{{ puffer }}/d" class="button">Boards</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue