Compare commits
No commits in common. "050d45ee2e0c0a89fba38740d442f64c44ab91cd" and "96478fb5d2de853ba9abcf1d5c46b6bdee8746df" have entirely different histories.
050d45ee2e
...
96478fb5d2
17 changed files with 99 additions and 214 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -278,8 +278,6 @@ dependencies = [
|
|||
"rmp-serde",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum 0.27.1",
|
||||
"strum_macros",
|
||||
"time",
|
||||
"tokio",
|
||||
"tower-http",
|
||||
|
@ -4148,7 +4146,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
"strum 0.26.3",
|
||||
"strum",
|
||||
"thiserror 1.0.69",
|
||||
"time",
|
||||
"tracing",
|
||||
|
@ -4909,25 +4907,6 @@ version = "0.26.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
|
|
|
@ -36,7 +36,5 @@ once_cell = "1.19.0"
|
|||
chrono = "0.4.33"
|
||||
rand = "0.8.5"
|
||||
url_encoded_data = "0.6.1"
|
||||
strum = "0.27.1"
|
||||
strum_macros = "0.27.1"
|
||||
|
||||
env_logger = "*"
|
||||
|
|
|
@ -657,4 +657,4 @@ pub async fn admin_user_list(
|
|||
} else {
|
||||
Redirect::to("/").into_response()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@ use tracing::{debug, error};
|
|||
use tracing::log::warn;
|
||||
use crate::{Opts, ALPHA, BUILT_ON, GIT_COMMIT, VERSION, YEAR};
|
||||
use crate::routes::index::FrontpageAnnouncement;
|
||||
use crate::routes::Themes;
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
struct FullAnnouncement {
|
||||
|
@ -97,7 +96,7 @@ pub struct AnnouncementTemplate {
|
|||
built_on: String,
|
||||
year: String,
|
||||
alpha: bool,
|
||||
theme: Themes,
|
||||
theme: String,
|
||||
announcement: FullAnnouncement,
|
||||
}
|
||||
|
||||
|
@ -110,10 +109,10 @@ pub async fn announcement_full(Extension(nats): Extension<Arc<jetstream::Context
|
|||
built_on: BUILT_ON.to_string(),
|
||||
year: YEAR.to_string(),
|
||||
alpha: ALPHA,
|
||||
theme: Themes::Default,
|
||||
theme: "default".to_string(),
|
||||
announcement,
|
||||
}.into_response()
|
||||
} else {
|
||||
StatusCode::NOT_FOUND.into_response()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ use tokio::sync::Mutex;
|
|||
use tracing::error;
|
||||
use tracing::log::warn;
|
||||
use crate::{BUILT_ON, GIT_COMMIT, Opts, ALPHA, VERSION, WEBSITE_COUNT, YEAR};
|
||||
use crate::routes::{authenticate_user, Themes, UserInfo};
|
||||
use crate::routes::{authenticate_user, UserInfo};
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct FrontpageAnnouncement {
|
||||
|
@ -102,7 +102,7 @@ pub fn frontpage_error(error: &str, auth_url: String) -> FrontpageTemplate {
|
|||
year: YEAR.to_string(),
|
||||
alpha: ALPHA,
|
||||
count: WEBSITE_COUNT.load(Ordering::Relaxed),
|
||||
theme: Themes::Default,
|
||||
theme: "default".to_string(),
|
||||
announcement: None,
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ pub struct FrontpageTemplate {
|
|||
year: String,
|
||||
alpha: bool,
|
||||
count: u64,
|
||||
theme: Themes,
|
||||
theme: String,
|
||||
announcement: Option<FrontpageAnnouncement>,
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ pub async fn frontpage(
|
|||
year: YEAR.to_string(),
|
||||
alpha: ALPHA,
|
||||
count: WEBSITE_COUNT.load(Ordering::Relaxed),
|
||||
theme: Themes::Default,
|
||||
theme: "default".to_string(),
|
||||
announcement,
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ struct IndexTemplate {
|
|||
year: String,
|
||||
alpha: bool,
|
||||
count: u64,
|
||||
theme: Themes,
|
||||
theme: String,
|
||||
announcement: Option<FrontpageAnnouncement>,
|
||||
}
|
||||
|
||||
|
@ -234,7 +234,7 @@ pub async fn index(
|
|||
return (jar.remove("token"), frontpage_error(e.as_str(), opts.auth_url.clone())).into_response();
|
||||
}
|
||||
};
|
||||
let theme = info.get_theme();
|
||||
let theme = info.theme.clone();
|
||||
|
||||
let announcement = latest_announcement(nats.clone()).await;
|
||||
|
||||
|
@ -260,7 +260,7 @@ pub async fn index(
|
|||
year: YEAR.to_string(),
|
||||
alpha: ALPHA,
|
||||
count: WEBSITE_COUNT.load(Ordering::Relaxed),
|
||||
theme: Themes::Default,
|
||||
theme: "default".to_string(),
|
||||
announcement,
|
||||
}.into_response()
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
|
||||
use std::sync::Arc;
|
||||
use askama::Template;
|
||||
use askama_axum::IntoResponse;
|
||||
|
@ -22,13 +21,7 @@ use asklyphe_common::nats::comms::ServiceResponse;
|
|||
use async_nats::jetstream;
|
||||
use axum::http::StatusCode;
|
||||
use serde::Serialize;
|
||||
use strum::IntoEnumIterator;
|
||||
use strum_macros::EnumIter;
|
||||
use time::macros::utc_datetime;
|
||||
use time::{OffsetDateTime, UtcDateTime};
|
||||
use tracing::{debug, error};
|
||||
|
||||
const RANDOM_THEME_EPOCH: UtcDateTime = utc_datetime!(2025-03-19 00:00);
|
||||
use tracing::error;
|
||||
|
||||
pub mod search;
|
||||
pub mod index;
|
||||
|
@ -37,102 +30,7 @@ pub mod user_settings;
|
|||
pub mod admin;
|
||||
pub mod announcement;
|
||||
|
||||
#[derive(Default, EnumIter, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Themes {
|
||||
Classic,
|
||||
Dark,
|
||||
#[default]
|
||||
Default,
|
||||
Freaky,
|
||||
Gloss,
|
||||
Oled,
|
||||
Water,
|
||||
Random
|
||||
}
|
||||
|
||||
impl Themes {
|
||||
pub fn get_all_themes() -> Vec<Themes> {
|
||||
Self::iter().collect()
|
||||
}
|
||||
|
||||
pub fn display_name(&self) -> String {
|
||||
match self {
|
||||
Themes::Classic => {
|
||||
"classic".to_string()
|
||||
}
|
||||
Themes::Dark => {
|
||||
"dark theme".to_string()
|
||||
}
|
||||
Themes::Default => {
|
||||
"default theme".to_string()
|
||||
}
|
||||
Themes::Freaky => {
|
||||
"freaky".to_string()
|
||||
}
|
||||
Themes::Gloss => {
|
||||
"gloss".to_string()
|
||||
}
|
||||
Themes::Oled => {
|
||||
"lights out".to_string()
|
||||
}
|
||||
Themes::Water => {
|
||||
"water".to_string()
|
||||
}
|
||||
Themes::Random => {
|
||||
"random".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn internal_name(&self) -> String {
|
||||
match self {
|
||||
Themes::Classic => {
|
||||
"classic".to_string()
|
||||
}
|
||||
Themes::Dark => {
|
||||
"dark".to_string()
|
||||
}
|
||||
Themes::Default => {
|
||||
"default".to_string()
|
||||
}
|
||||
Themes::Freaky => {
|
||||
"freaky".to_string()
|
||||
}
|
||||
Themes::Gloss => {
|
||||
"gloss".to_string()
|
||||
}
|
||||
Themes::Oled => {
|
||||
"oled".to_string()
|
||||
}
|
||||
Themes::Water => {
|
||||
"water".to_string()
|
||||
}
|
||||
Themes::Random => {
|
||||
"random".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Themes {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"classic" => Ok(Themes::Classic),
|
||||
"dark" => Ok(Themes::Dark),
|
||||
"default" => Ok(Themes::Default),
|
||||
"freaky" => Ok(Themes::Freaky),
|
||||
"gloss" => Ok(Themes::Gloss),
|
||||
"oled" => Ok(Themes::Oled),
|
||||
"water" => Ok(Themes::Water),
|
||||
"random" => Ok(Themes::Random),
|
||||
_ => Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
#[derive(Serialize)]
|
||||
pub struct UserInfo {
|
||||
pub username: String,
|
||||
pub email: String,
|
||||
|
@ -141,27 +39,6 @@ pub struct UserInfo {
|
|||
pub administrator: bool,
|
||||
}
|
||||
|
||||
impl UserInfo {
|
||||
pub fn get_theme(&self) -> Themes {
|
||||
let theme: Themes = self.theme.parse().unwrap_or_default();
|
||||
|
||||
if theme.eq(&Themes::Random) {
|
||||
let possible_themes = Themes::get_all_themes();
|
||||
let current_day = UtcDateTime::now();
|
||||
|
||||
let rand_value = (((current_day - RANDOM_THEME_EPOCH).as_seconds_f64() / 86400.0) % possible_themes.len() as f64) as usize;
|
||||
|
||||
*possible_themes.get(rand_value).unwrap_or(&Themes::Default)
|
||||
} else {
|
||||
theme
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_true_theme(&self) -> Themes {
|
||||
self.theme.parse().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn authenticate_user(nats: Arc<jetstream::Context>, token: String) -> Result<UserInfo, String> {
|
||||
let response = comms::query_service(
|
||||
comms::Query::AuthService(AuthServiceQuery {
|
||||
|
@ -237,4 +114,4 @@ pub struct NotFoundTemplate;
|
|||
|
||||
pub async fn not_found() -> impl IntoResponse {
|
||||
(StatusCode::NOT_FOUND, NotFoundTemplate).into_response()
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
*/
|
||||
|
||||
use crate::routes::index::frontpage_error;
|
||||
use crate::routes::{authenticate_user, Themes, UserInfo};
|
||||
use crate::routes::{authenticate_user, UserInfo};
|
||||
use crate::searchbot::{gather_image_results, gather_search_results};
|
||||
use crate::unit_converter;
|
||||
use crate::unit_converter::UnitConversion;
|
||||
|
@ -111,7 +111,7 @@ struct SearchTemplateJavascript {
|
|||
built_on: String,
|
||||
year: String,
|
||||
alpha: bool,
|
||||
theme: Themes,
|
||||
theme: String,
|
||||
}
|
||||
|
||||
pub async fn search_js(
|
||||
|
@ -121,7 +121,7 @@ pub async fn search_js(
|
|||
Extension(opts): Extension<Opts>,
|
||||
) -> impl IntoResponse {
|
||||
fn error_response(query: String, info: UserInfo, error: &str) -> SearchTemplateJavascript {
|
||||
let theme = info.get_theme();
|
||||
let theme = info.theme.clone();
|
||||
let querystr = url_encoded_data::stringify(&[("q", query.as_str())]);
|
||||
SearchTemplateJavascript {
|
||||
info,
|
||||
|
@ -175,7 +175,7 @@ pub async fn search_js(
|
|||
query = query.replace("-complications", "");
|
||||
}
|
||||
|
||||
let theme = info.get_theme();
|
||||
let theme = info.theme.clone();
|
||||
let querystr = url_encoded_data::stringify(&[("q", og_query.as_str())]);
|
||||
SearchTemplateJavascript {
|
||||
info,
|
||||
|
@ -217,7 +217,7 @@ pub struct SearchTemplate {
|
|||
pub built_on: String,
|
||||
pub year: String,
|
||||
pub alpha: bool,
|
||||
pub theme: Themes,
|
||||
pub theme: String,
|
||||
}
|
||||
|
||||
pub async fn search_nojs(
|
||||
|
@ -227,7 +227,7 @@ pub async fn search_nojs(
|
|||
Extension(opts): Extension<Opts>,
|
||||
) -> impl IntoResponse {
|
||||
fn error_response(query: String, info: UserInfo, error: &str) -> SearchTemplate {
|
||||
let theme = info.get_theme();
|
||||
let theme = info.theme.clone();
|
||||
let querystr = url_encoded_data::stringify(&[("q", query.as_str())]);
|
||||
SearchTemplate {
|
||||
info,
|
||||
|
@ -416,7 +416,7 @@ pub struct ImageSearchTemplate {
|
|||
pub built_on: String,
|
||||
pub year: String,
|
||||
pub alpha: bool,
|
||||
pub theme: Themes,
|
||||
pub theme: String,
|
||||
}
|
||||
pub async fn image_search(
|
||||
jar: CookieJar,
|
||||
|
@ -425,7 +425,7 @@ pub async fn image_search(
|
|||
Extension(opts): Extension<Opts>,
|
||||
) -> impl IntoResponse {
|
||||
fn error_response(query: String, info: UserInfo, error: &str) -> ImageSearchTemplate {
|
||||
let theme = info.get_theme();
|
||||
let theme = info.theme.clone();
|
||||
let querystr = url_encoded_data::stringify(&[("q", query.as_str())]);
|
||||
ImageSearchTemplate {
|
||||
info,
|
||||
|
|
|
@ -27,12 +27,49 @@ use serde::Deserialize;
|
|||
use tokio::sync::Mutex;
|
||||
use tracing::error;
|
||||
use crate::{BUILT_ON, GIT_COMMIT, Opts, ALPHA, VERSION, WEBSITE_COUNT, YEAR};
|
||||
use crate::routes::{authenticate_user, Themes, UserInfo};
|
||||
use crate::routes::{authenticate_user, UserInfo};
|
||||
|
||||
pub struct Theme<'a> {
|
||||
pub value: &'a str,
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
pub static THEMES: &[Theme] = &[
|
||||
Theme {
|
||||
value: "default",
|
||||
name: "default theme",
|
||||
},
|
||||
Theme {
|
||||
value: "dark",
|
||||
name: "dark theme",
|
||||
},
|
||||
Theme {
|
||||
value: "oled",
|
||||
name: "lights out",
|
||||
},
|
||||
Theme {
|
||||
value: "classic",
|
||||
name: "classic",
|
||||
},
|
||||
Theme {
|
||||
value: "freaky",
|
||||
name: "freaky",
|
||||
},
|
||||
Theme {
|
||||
value: "water",
|
||||
name: "water",
|
||||
},
|
||||
Theme {
|
||||
value: "gloss",
|
||||
name: "gloss",
|
||||
},
|
||||
];
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "user_settings.html")]
|
||||
pub struct SettingsTemplate {
|
||||
themes: Vec<Themes>,
|
||||
themes: &'static [Theme<'static>],
|
||||
|
||||
error: Option<String>,
|
||||
|
||||
info: UserInfo,
|
||||
|
@ -43,8 +80,7 @@ pub struct SettingsTemplate {
|
|||
year: String,
|
||||
alpha: bool,
|
||||
count: u64,
|
||||
theme: Themes,
|
||||
true_theme: Themes,
|
||||
theme: String,
|
||||
}
|
||||
|
||||
pub async fn user_settings(
|
||||
|
@ -60,11 +96,11 @@ pub async fn user_settings(
|
|||
return (jar.remove("token"), crate::routes::index::frontpage_error(e.as_str(), opts.auth_url.clone())).into_response();
|
||||
}
|
||||
};
|
||||
let theme = info.get_theme();
|
||||
let theme = info.theme.clone();
|
||||
SettingsTemplate {
|
||||
themes: Themes::get_all_themes(),
|
||||
themes: THEMES,
|
||||
error: None,
|
||||
info: info.clone(),
|
||||
info,
|
||||
search_query: "".to_string(),
|
||||
version: VERSION.to_string(),
|
||||
git_commit: GIT_COMMIT.to_string(),
|
||||
|
@ -73,7 +109,6 @@ pub async fn user_settings(
|
|||
alpha: ALPHA,
|
||||
count: WEBSITE_COUNT.load(Ordering::Relaxed),
|
||||
theme,
|
||||
true_theme: info.get_true_theme(),
|
||||
}.into_response()
|
||||
} else {
|
||||
Redirect::temporary("/").into_response()
|
||||
|
@ -91,11 +126,11 @@ pub async fn theme_change_post(
|
|||
Extension(opts): Extension<Opts>,
|
||||
Form(input): Form<ThemeChangeForm>,
|
||||
) -> impl IntoResponse {
|
||||
fn settings_error(info: UserInfo, theme: Themes, error: String) -> impl IntoResponse {
|
||||
fn settings_error(info: UserInfo, theme: String, error: String) -> impl IntoResponse {
|
||||
SettingsTemplate {
|
||||
themes: Themes::get_all_themes(),
|
||||
themes: THEMES,
|
||||
error: Some(error),
|
||||
info: info.clone(),
|
||||
info,
|
||||
search_query: "".to_string(),
|
||||
version: VERSION.to_string(),
|
||||
git_commit: GIT_COMMIT.to_string(),
|
||||
|
@ -104,7 +139,6 @@ pub async fn theme_change_post(
|
|||
alpha: ALPHA,
|
||||
count: WEBSITE_COUNT.load(Ordering::Relaxed),
|
||||
theme,
|
||||
true_theme: info.get_true_theme(),
|
||||
}.into_response()
|
||||
}
|
||||
|
||||
|
@ -117,12 +151,10 @@ pub async fn theme_change_post(
|
|||
}
|
||||
};
|
||||
|
||||
let theme = info.get_theme();
|
||||
|
||||
if let Some(theme_input) = &input.theme {
|
||||
if !Themes::get_all_themes().iter().map(|x| x.internal_name().to_string()).collect::<Vec<String>>().contains(&theme_input) {
|
||||
return settings_error(info, theme.clone(), "invalid input, please try again!".to_string()).into_response();
|
||||
}
|
||||
let theme = info.theme.clone();
|
||||
|
||||
if !THEMES.iter().map(|v| v.value.to_string()).collect::<Vec<String>>().contains(&input.theme.clone().unwrap_or("default".to_string())) {
|
||||
return settings_error(info, theme, "invalid input, please try again!".to_string()).into_response();
|
||||
}
|
||||
|
||||
let response = comms::query_service(comms::Query::AuthService(AuthServiceQuery {
|
||||
|
@ -168,4 +200,4 @@ pub async fn theme_change_post(
|
|||
} else {
|
||||
Redirect::to("/").into_response()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -341,7 +341,7 @@ pub async fn gather_search_results(nats: Arc<jetstream::Context>, query: &str, u
|
|||
search_results.remove(rm - i);
|
||||
}
|
||||
|
||||
let theme = user_info.get_theme();
|
||||
let theme = user_info.theme.clone();
|
||||
let querystr = url_encoded_data::stringify(&[("q", query)]);
|
||||
SearchTemplate {
|
||||
info: user_info,
|
||||
|
@ -489,7 +489,7 @@ pub async fn gather_image_results(nats: Arc<jetstream::Context>, query: &str, us
|
|||
result.src = format!("/imgproxy?{}", url);
|
||||
}
|
||||
|
||||
let theme = user_info.get_theme();
|
||||
let theme = user_info.theme.clone();
|
||||
ImageSearchTemplate {
|
||||
info: user_info,
|
||||
error: None,
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
{% block title %}the best search engine{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/frontpage.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/inline-announcement.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/frontpage.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/inline-announcement.css"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block page %}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/static/themes/default/home.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/home.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/inline-announcement.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/home.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/inline-announcement.css"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block page %}
|
||||
|
@ -71,4 +71,4 @@
|
|||
</div>
|
||||
{% include "ui/footer.html" %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/static/themes/default/imagesearch.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/imagesearch.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/imagesearch.css"/>
|
||||
{% if search_query == "notnite" %}<link rel="stylesheet" href="/static/creature.css"/>{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -61,4 +61,4 @@
|
|||
|
||||
{% include "ui/footer.html" %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/static/themes/default/search.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/search.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/search.css"/>
|
||||
{% if search_query == "notnite" %}<link rel="stylesheet" href="/static/creature.css"/>{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
@ -97,4 +97,4 @@
|
|||
|
||||
{% include "ui/footer.html" %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/static/themes/default/search.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/search.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/search.css"/>
|
||||
{% if search_query == "notnite" %}<link rel="stylesheet" href="/static/creature.css"/>{% endif %}
|
||||
<script src="/static/js/search.js" defer></script>
|
||||
{% endblock %}
|
||||
|
@ -76,4 +76,4 @@
|
|||
|
||||
{% include "ui/footer.html" %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -12,11 +12,11 @@
|
|||
href="/static/osd.xml" />
|
||||
|
||||
<link rel="stylesheet" href="/static/themes/default/shell.css" />
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/shell.css" />
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/shell.css" />
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% block page %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/static/themes/default/settings.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme.internal_name()}}/settings.css"/>
|
||||
<link rel="stylesheet" href="/static/themes/{{theme}}/settings.css"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block page %}
|
||||
|
@ -43,15 +43,16 @@
|
|||
<div class="settings-row">
|
||||
<div id="theme" class="settings-section">
|
||||
<h2>theme</h2>
|
||||
<p>your current theme is: "{{true_theme.display_name()}}"</p>
|
||||
{% if true_theme.internal_name() != theme.internal_name() %}
|
||||
<p>today's random theme is {{ theme.display_name() }}</p>
|
||||
{% endif %}
|
||||
{% for t in themes %}
|
||||
{%if theme==t.value%}
|
||||
<p>your current theme is: "{{t.name}}"</p>
|
||||
{%endif%}
|
||||
{% endfor %}
|
||||
<form action="/user_settings/set_theme" method="post">
|
||||
<label for="theme-selector">theme</label>
|
||||
<select name="theme" id="theme-selector">
|
||||
{% for t in themes %}
|
||||
<option value="{{t.internal_name()}}" {%if true_theme.internal_name()==t.internal_name()%}selected{%endif%}>{{t.display_name()}}</option>
|
||||
<option value="{{t.value}}" {%if theme==t.value%}selected{%endif%}>{{t.name}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="submit" id="theme-submit">change theme!</button>
|
||||
|
@ -64,4 +65,4 @@
|
|||
|
||||
{% include "ui/footer.html" %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -457,7 +457,6 @@ pub async fn user_count(db: &DatabaseConnection) -> Result<usize, FetchUserError
|
|||
/// returns the number of users in the database who are admins
|
||||
pub async fn admin_count(db: &DatabaseConnection) -> Result<usize, FetchUserError> {
|
||||
// dont fucking touch this, i don't know why it works but it does, it's actually evil
|
||||
// note: doesn't work
|
||||
Ok(user::Entity::find().filter(user::Column::Flags.into_expr().binary(BinOper::LShift, Expr::value(63 - 2)).lt(1 << (63 - 2)))
|
||||
.count(db).await.map_err(|e| {
|
||||
error!("DATABASE ERROR WHILE ADMINCOUNT: {e}");
|
||||
|
@ -483,4 +482,4 @@ pub async fn email_list(db: &DatabaseConnection) -> Result<Vec<(String, String)>
|
|||
})?.into_iter().map(|v| {
|
||||
(v.username, v.email)
|
||||
}).collect())
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue