Compare commits
No commits in common. "dev-0.6.1" and "main" have entirely different histories.
11 changed files with 608 additions and 646 deletions
1
.envrc
1
.envrc
|
@ -1 +0,0 @@
|
||||||
use flake
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -27,6 +27,3 @@ dist-ssr
|
||||||
|
|
||||||
/target
|
/target
|
||||||
.sass-cache/
|
.sass-cache/
|
||||||
|
|
||||||
# Manual (nix flake)
|
|
||||||
.direnv
|
|
1
.tool-versions
Normal file
1
.tool-versions
Normal file
|
@ -0,0 +1 @@
|
||||||
|
nodejs 19.9.0
|
995
Cargo.lock
generated
995
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "portfolio"
|
name = "portfolio"
|
||||||
version = "0.6.1"
|
version = "0.6.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
@ -32,8 +32,8 @@ actix-files = { version = "0.6", optional = true }
|
||||||
actix-web = { version = "4.5", features = ["macros"], optional = true }
|
actix-web = { version = "4.5", features = ["macros"], optional = true }
|
||||||
leptos_actix = { version = "0.6", optional = true }
|
leptos_actix = { version = "0.6", optional = true }
|
||||||
futures = { version = "0.3", optional = true }
|
futures = { version = "0.3", optional = true }
|
||||||
simple_logger = { version = "5.0", optional = true }
|
simple_logger = { version = "4.3", optional = true }
|
||||||
pulldown-cmark = { version = "0.11", optional = true } # Markdown parser
|
pulldown-cmark = { version = "0.10", optional = true } # Markdown parser
|
||||||
gray_matter = { version = "0.2", optional = true } # frontmatter parser
|
gray_matter = { version = "0.2", optional = true } # frontmatter parser
|
||||||
serde_yaml = { version = "0.9", optional = true }
|
serde_yaml = { version = "0.9", optional = true }
|
||||||
anyhow = { version = "1.0", optional = true }
|
anyhow = { version = "1.0", optional = true }
|
||||||
|
|
|
@ -7,8 +7,8 @@ description: Ma première configuration et ma première contribution à l'enviro
|
||||||
project_link: none
|
project_link: none
|
||||||
draft: true
|
draft: true
|
||||||
tags:
|
tags:
|
||||||
- KDE
|
- kde
|
||||||
- Linux
|
- linux
|
||||||
---
|
---
|
||||||
|
|
||||||
## Rapide rappel à propos de KDE
|
## Rapide rappel à propos de KDE
|
||||||
|
|
|
@ -7,8 +7,8 @@ description: Installation de pmbootstrap et compilation d'un paquet Postmarket O
|
||||||
project_link: none
|
project_link: none
|
||||||
draft: true
|
draft: true
|
||||||
tags:
|
tags:
|
||||||
- Postmarket OS
|
- pmOS
|
||||||
- Linux
|
- linux
|
||||||
---
|
---
|
||||||
|
|
||||||
## À propos de Postmarket OS
|
## À propos de Postmarket OS
|
||||||
|
@ -68,18 +68,11 @@ git -C $workdir checkout [branch]
|
||||||
## Compilation de notre paquet Alpine
|
## Compilation de notre paquet Alpine
|
||||||
|
|
||||||
Pour compiler le paquet, on utilise la commande `pmbootstrap build [paquet_name]`.
|
Pour compiler le paquet, on utilise la commande `pmbootstrap build [paquet_name]`.
|
||||||
> Avant de compiler depuis le repository Nightly, il faut d'abord rajouter la clef de signature
|
|
||||||
>
|
|
||||||
> `wget https://nightly.postmarketos.org/plasma-mobile/pmos@local-662fcd2f.rsa.pub`
|
|
||||||
>
|
|
||||||
> `mv pmos@local-662fcd2f.rsa.pub $(pmbootstrap config work)/config_apk_keys/`
|
|
||||||
>
|
|
||||||
> Source : https://wiki.postmarketos.org/wiki/Nightly
|
|
||||||
|
|
||||||
_Exemple de commande_
|
_Exemple de commande_
|
||||||
```bash
|
```bash
|
||||||
pmbootstrap \
|
pmbootstrap \
|
||||||
-mp https://nightly.postmarketos.org/plasma-mobile/packages/ \
|
-mp https://nightly.postmarketos.org/plasma-mobile/paquets/ \
|
||||||
-mp http://mirror.postmarketos.org/postmarketos/ \
|
-mp http://mirror.postmarketos.org/postmarketos/ \
|
||||||
--details-to-stdout \
|
--details-to-stdout \
|
||||||
-j 32 \
|
-j 32 \
|
||||||
|
@ -96,7 +89,7 @@ Dans cet exemple, j'ai utilisé les arguments suivants:
|
||||||
* `-mp` : Permet de définir un repository Alpine pour installer les paquets.
|
* `-mp` : Permet de définir un repository Alpine pour installer les paquets.
|
||||||
> Dans l'exemple, j'utilise deux repos
|
> Dans l'exemple, j'utilise deux repos
|
||||||
>
|
>
|
||||||
> `https://nightly.postmarketos.org/plasma-mobile/packages/` : Contient la version en cours de développement de KDE Plasma Mobile
|
> `https://nightly.postmarketos.org/plasma-mobile/paquets/` : Contient la version en cours de développement de KDE Plasma Mobile
|
||||||
>
|
>
|
||||||
> `http://mirror.postmarketos.org/postmarketos/` : Le miroir officiel de Postmarket OS
|
> `http://mirror.postmarketos.org/postmarketos/` : Le miroir officiel de Postmarket OS
|
||||||
|
|
||||||
|
|
85
flake.lock
85
flake.lock
|
@ -1,85 +0,0 @@
|
||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"flake-utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710146030,
|
|
||||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1717112898,
|
|
||||||
"narHash": "sha256-7R2ZvOnvd9h8fDd65p0JnB7wXfUvreox3xFdYWd1BnY=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "6132b0f6e344ce2fe34fc051b72fb46e34f668e0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixpkgs-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"rust-overlay": "rust-overlay"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rust-overlay": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": [
|
|
||||||
"flake-utils"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1717294752,
|
|
||||||
"narHash": "sha256-QhlS52cEQyx+iVcgrEoCnEEpWUA6uLdmeLRxk935inI=",
|
|
||||||
"owner": "oxalica",
|
|
||||||
"repo": "rust-overlay",
|
|
||||||
"rev": "b46857a406d207a1de74e792ef3b83e800c30e08",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "oxalica",
|
|
||||||
"repo": "rust-overlay",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
36
flake.nix
36
flake.nix
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
description = "Portfolio rust configuration";
|
|
||||||
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
|
||||||
rust-overlay = {
|
|
||||||
url = "github:oxalica/rust-overlay";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
inputs.flake-utils.follows = "flake-utils";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils, rust-overlay }:
|
|
||||||
flake-utils.lib.eachSystem flake-utils.lib.allSystems (system:
|
|
||||||
let
|
|
||||||
overlays = [ (import rust-overlay) ];
|
|
||||||
pkgs = import nixpkgs {
|
|
||||||
inherit system overlays;
|
|
||||||
};
|
|
||||||
rust = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
|
|
||||||
nodejs = pkgs.nodejs_20;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
devShells = {
|
|
||||||
default = pkgs.mkShell {
|
|
||||||
buildInputs = [
|
|
||||||
(rust.override { extensions = ["rust-src" "rust-analyzer"]; })
|
|
||||||
nodejs
|
|
||||||
pkgs.cargo-leptos
|
|
||||||
pkgs.dart-sass
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -9,7 +9,6 @@ cfg_if::cfg_if! {
|
||||||
pub posts: Vec<Arc<Post>>,
|
pub posts: Vec<Arc<Post>>,
|
||||||
pub posts_by_slug: HashMap<String, Arc<Post>>,
|
pub posts_by_slug: HashMap<String, Arc<Post>>,
|
||||||
pub posts_by_tag: HashMap<String, Vec<Arc<Post>>>,
|
pub posts_by_tag: HashMap<String, Vec<Arc<Post>>>,
|
||||||
pub tags: Vec<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Data {
|
impl Data {
|
||||||
|
@ -22,8 +21,6 @@ cfg_if::cfg_if! {
|
||||||
.map(Arc::new)
|
.map(Arc::new)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|
||||||
let mut tags : Vec<String> = Vec::new();
|
|
||||||
let mut posts_by_slug : HashMap<String, Arc<Post>> = HashMap::new();
|
let mut posts_by_slug : HashMap<String, Arc<Post>> = HashMap::new();
|
||||||
let mut posts_by_tag : HashMap<String, Vec<Arc<Post>>> = HashMap::new();
|
let mut posts_by_tag : HashMap<String, Vec<Arc<Post>>> = HashMap::new();
|
||||||
|
|
||||||
|
@ -31,26 +28,19 @@ cfg_if::cfg_if! {
|
||||||
posts_by_slug.insert(post.metadata.slug.clone(), post.clone());
|
posts_by_slug.insert(post.metadata.slug.clone(), post.clone());
|
||||||
|
|
||||||
for tag in &post.metadata.tags {
|
for tag in &post.metadata.tags {
|
||||||
let tag_lower = tag.to_lowercase();
|
let tag = tag.to_lowercase();
|
||||||
|
let posts = posts_by_tag.entry(tag).or_default();
|
||||||
if let None = tags.iter().find(|t| t.to_lowercase().eq(&tag_lower)) {
|
|
||||||
tags.push(tag.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let posts = posts_by_tag.entry(tag_lower).or_default();
|
|
||||||
posts.push(post.clone());
|
posts.push(post.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!("Loaded {} posts", posts.len());
|
log::info!("Loaded {} posts", posts.len());
|
||||||
log::info!("Found {} tags in global", tags.len());
|
log::info!("Found {} tags", posts_by_tag.len());
|
||||||
log::info!("Found {} tags from posts", posts_by_tag.len());
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
posts,
|
posts,
|
||||||
posts_by_slug,
|
posts_by_slug,
|
||||||
posts_by_tag,
|
posts_by_tag,
|
||||||
tags
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub async fn get_posts(
|
||||||
|
|
||||||
let default = vec![];
|
let default = vec![];
|
||||||
let posts = match tag {
|
let posts = match tag {
|
||||||
Some(tag) => data.posts_by_tag.get(&tag.to_lowercase()).unwrap_or(&default),
|
Some(tag) => data.posts_by_tag.get(&tag).unwrap_or(&default),
|
||||||
None => &data.posts
|
None => &data.posts
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,16 +32,6 @@ pub async fn get_posts(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[server]
|
|
||||||
pub async fn get_tags() -> Result<Vec<String>, ServerFnError> {
|
|
||||||
let data : actix_web::web::Data<crate::app::models::Data> = leptos_actix::extract().await?;
|
|
||||||
let data = data.into_inner();
|
|
||||||
let mut tags = data.tags.clone();
|
|
||||||
tags.sort();
|
|
||||||
|
|
||||||
Ok(tags)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
pub async fn get_post(
|
pub async fn get_post(
|
||||||
slug: String
|
slug: String
|
||||||
|
@ -127,7 +117,6 @@ pub fn PostList() -> impl IntoView {
|
||||||
let query = use_query_map();
|
let query = use_query_map();
|
||||||
let tag = move || query.with(|query| query.get("tag").cloned());
|
let tag = move || query.with(|query| query.get("tag").cloned());
|
||||||
let posts = create_resource(move || tag(), move |_| get_posts(tag()));
|
let posts = create_resource(move || tag(), move |_| get_posts(tag()));
|
||||||
let tags = create_resource(|| (), move |_| get_tags());
|
|
||||||
|
|
||||||
let posts_view = move || {
|
let posts_view = move || {
|
||||||
posts.and_then(|posts| {
|
posts.and_then(|posts| {
|
||||||
|
@ -137,39 +126,18 @@ pub fn PostList() -> impl IntoView {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let tags_view = move || {
|
|
||||||
tags.and_then(|tags| {
|
|
||||||
tags.iter()
|
|
||||||
.map(|tag| {
|
|
||||||
let tag = tag.clone();
|
|
||||||
view! { <A class="tag" href=format!("/posts?tag={}", tag.clone())>{tag}</A> }
|
|
||||||
})
|
|
||||||
.collect_view()
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let filter_view = move || {
|
let filter_view = move || {
|
||||||
match tag() {
|
tag().map(|tag| Some(view! {
|
||||||
Some(tag) => {
|
<div class="mx-auto max-w-3xl mb-5">
|
||||||
view! {
|
Tag sélectionné : <A class="tag" href="/posts".to_string()>{tag}<leptos_icons::Icon icon=icondata::IoClose class="scale-125 ml-1 inline" /></A>
|
||||||
<><A class="tag" href="/posts".to_string()>{tag}<leptos_icons::Icon icon=icondata::IoClose class="scale-125 ml-1 inline" /></A></>
|
</div>
|
||||||
}.into_view()
|
}))
|
||||||
},
|
|
||||||
None => {
|
|
||||||
view! {
|
|
||||||
<>{tags_view}</>
|
|
||||||
}.into_view()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<Suspense fallback=move || view! { <Loading title="Chargement des posts...".to_string() /> }>
|
<Suspense fallback=move || view! { <Loading title="Chargement des posts...".to_string() /> }>
|
||||||
<Nav/>
|
<Nav/>
|
||||||
<div class="mx-auto max-w-3xl mb-5 flex flex-wrap gap-2">
|
|
||||||
<span>Filtre : </span>
|
|
||||||
{filter_view}
|
{filter_view}
|
||||||
</div>
|
|
||||||
<main class="posts">
|
<main class="posts">
|
||||||
<div class="posts__cards">{posts_view}</div>
|
<div class="posts__cards">{posts_view}</div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -184,26 +152,26 @@ pub fn PostElement() -> impl IntoView {
|
||||||
|
|
||||||
let post = create_resource(|| (), move |_| get_post(slug()));
|
let post = create_resource(|| (), move |_| get_post(slug()));
|
||||||
|
|
||||||
let render_draft_notice = |post: &Post| -> Option<View> {
|
let post_view = move || {
|
||||||
|
post.and_then(|post| {
|
||||||
|
view! {
|
||||||
|
<>
|
||||||
|
{
|
||||||
if post.metadata.draft {
|
if post.metadata.draft {
|
||||||
return Some(view! {
|
Some(view!{
|
||||||
<div class="bg-warning text-on_warning dark:bg-dark_warning dark:text-dart_on_warning rounded-md p-5 mb-5">
|
<div class="bg-warning text-on_warning dark:bg-dark_warning dark:text-dart_on_warning rounded-md p-5 mb-5">
|
||||||
r#"
|
r#"
|
||||||
L'article est en cours d'écriture. La formulation peut ne pas être exacte et les phrases peuvent contenir des fautes.
|
L'article est en cours d'écriture. La formulation peut ne pas être exacte et les phrases peuvent contenir des fautes.
|
||||||
"#
|
"#
|
||||||
</div>
|
</div>
|
||||||
}.into_view());
|
})
|
||||||
}
|
} else {
|
||||||
None
|
None
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let render_post_view = move || {
|
|
||||||
post.and_then(|post| {
|
|
||||||
let draft_notice = render_draft_notice(&post);
|
|
||||||
view! {
|
|
||||||
<>
|
|
||||||
{draft_notice}
|
|
||||||
<PostHeader metadata=post.metadata.clone() full_element=true />
|
<PostHeader metadata=post.metadata.clone() full_element=true />
|
||||||
|
|
||||||
<div inner_html={post.content.clone()}></div>
|
<div inner_html={post.content.clone()}></div>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
@ -214,7 +182,7 @@ pub fn PostElement() -> impl IntoView {
|
||||||
<Suspense fallback=move || view! { <Loading title="Chargement du post...".to_string() /> }>
|
<Suspense fallback=move || view! { <Loading title="Chargement du post...".to_string() /> }>
|
||||||
<Nav/>
|
<Nav/>
|
||||||
<main class="post">
|
<main class="post">
|
||||||
{render_post_view}
|
{post_view}
|
||||||
<script>load();</script>
|
<script>load();</script>
|
||||||
</main>
|
</main>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
Loading…
Reference in a new issue