Skip to content

Commit

Permalink
even more btns, better linux undo support (v0.3.0)
Browse files Browse the repository at this point in the history
  • Loading branch information
opensourcecheemsburgers committed Jul 9, 2023
1 parent ba2fa37 commit fff6022
Show file tree
Hide file tree
Showing 39 changed files with 1,130 additions and 454 deletions.
46 changes: 46 additions & 0 deletions PKGBUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Maintainer: sukanka<su975853527 AT gmail dot com>
pkgname=ubiquity
pkgver=0.2.0
pkgrel=2
pkgdesc="An open-source and cross-platform markdown editor written in Rust."
arch=('x86_64')
url="https://github.com/opensourcecheemsburgers/ubiquity"
license=('GPL3')
depends=('webkit2gtk' 'libayatana-appindicator')
makedepends=('npm' 'rustup')
source=("${pkgname}-${pkgver}.tar.gz::${url}/archive/refs/tags/v${pkgver}.tar.gz"
"${pkgname}.desktop"
)

prepare(){
cd $srcdir/${pkgname}-${pkgver}
rustup default nightly
cargo install trunk
cargo install tauri-cli
cargo target add wasm32-unknown-unknown

cd frontend
npx tailwindcss -i ./css/input.css -o ./css/output.css --watch
}

build(){
cd $srcdir/${pkgname}-${pkgver}
# export HOME=$srcdir
export RUSTFLAGS="-L /usr/lib/quickjs"
yarn install
yarn run check
cargo-tauri build
}
package(){
cd $srcdir/${pkgname}-${pkgver}
install -Dm755 src-tauri/target/release/${pkgname} -t ${pkgdir}/usr/bin

install -d ${pkgdir}/usr/lib/${pkgname}/resources
ln -sf /etc/clash/Country.mmdb -t ${pkgdir}/usr/lib/${pkgname}/resources

install -Dm644 src/assets/image/logo.svg ${pkgdir}/usr/share/icons/hicolor/scalable/apps/${pkgname}.svg

install -Dm644 ${srcdir}/${pkgname}.desktop -t ${pkgdir}/usr/share/applications

}
q
7 changes: 5 additions & 2 deletions frontend/index.web.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta
http-equiv="Content-Security-Policy"
content="default-src blob: data: filesystem: ws: wss: http: https: tauri: 'wasm-unsafe-eval' 'self'; script-src blob: data: filesystem: ws: wss: http: https: tauri: 'wasm-unsafe-eval' 'self'" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
content="default-src * data: blob: filesystem: about: ws: wss: 'unsafe-inline' 'unsafe-eval';
script-src * data: blob: 'unsafe-inline' 'wasm-unsafe-eval';
style-src * data: blob: 'unsafe-inline';
font-src * data: blob: 'unsafe-inline';" />
<title>Ubiquity</title>
<link data-trunk rel="css" href="./css/fonts.css" />
<link data-trunk rel="css" href="./css/output.css" />
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/components/dropdown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// use yew::prelude::*;

// use crate::contexts::config::use_config;

// #[derive(Debug, PartialEq, Properties)]
// pub struct DropdownProps {
// pub children: Children,
// }


// #[function_component(Dropdown)]
// pub fn divider_y_axis(props: &DropdownProps) -> Html {
// let mut dropdown_classes = classes!("dropdown-content", "z-[1]", "menu", "p-2", "shadow", "bg-base-200", "rounded-box", "w-52", "lg:w-max");
// if !use_config().state().mobile_ui {
// dropdown_classes.push("dropdown-hover");
// }
// html! {
// <div class={dropdown_classes}>
// { props.children.clone() }
// </div>
// }
// }
4 changes: 2 additions & 2 deletions frontend/src/components/dual_view.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use yew::prelude::*;
use crate::components::container::HalfWidthContainer;
use crate::components::markdown_input::MarkdownInput;
use crate::components::editor::editor::Editor;
use crate::components::markdown_preview::MarkdownPreview;

#[function_component(DualView)]
Expand All @@ -19,7 +19,7 @@ pub fn dual_view() -> Html {
html! {
<div class={dual_view_classes}>
<HalfWidthContainer>
<MarkdownInput />
<Editor />
</HalfWidthContainer>
<HalfWidthContainer>
<MarkdownPreview />
Expand Down
14 changes: 14 additions & 0 deletions frontend/src/components/editor/editor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use yew::prelude::*;

use crate::components::editor::{header::header::EditorHeader, textarea::textarea::EditorTextarea};

#[function_component(Editor)]
pub fn editor() -> Html {

html! {
<div class="flex flex-col h-full overflow-visible">
<EditorHeader />
<EditorTextarea />
</div>
}
}
41 changes: 41 additions & 0 deletions frontend/src/components/editor/header/bold.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use wasm_bindgen::JsCast;
use web_sys::HtmlTextAreaElement;
use yew::prelude::*;
use crate::components::editor::header::header::HEADER_BTN_CLASSES;
use crate::components::tooltip::Tooltip;
use crate::contexts::markdown::{use_markdown, Markdown};
use crate::icons::BoldIcon;
use gloo::utils::document;

#[function_component(BoldBtn)]
pub fn bold_btn() -> Html {
let md_state = use_markdown();
let bold = Callback::from(move |mouse_event: MouseEvent| {
let text_area: HtmlTextAreaElement = document().get_element_by_id("editor").unwrap().dyn_into().unwrap();
let mut current_value = text_area.value();

if let Some(start) = text_area.selection_start().unwrap() &&
let Some(end) = text_area.selection_end().unwrap() {
let start_usize = start as usize;
let end_usize = end as usize;

current_value.insert_str(start_usize, "**");
current_value.insert_str(end_usize + 2, "**");
text_area.set_selection_end(Some(start + 2));
} else {
current_value.push_str("****");
text_area.set_selection_end(Some(2));
}
let key = md_state.state().key;
let md = Markdown::from(AttrValue::from(current_value), key);
md_state.update_markdown(md);
});

html! {
<Tooltip tip={"Bold"}>
<btn onclick={bold} class={HEADER_BTN_CLASSES}>
<BoldIcon />
</btn>
</Tooltip>
}
}
21 changes: 21 additions & 0 deletions frontend/src/components/editor/header/font_decrease.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use yew::prelude::*;
use crate::components::editor::header::header::HEADER_BTN_CLASSES;
use crate::contexts::config::use_config;
use crate::components::tooltip::Tooltip;
use crate::icons::MinusIcon;

#[function_component(FontDecreaseBtn)]
pub fn font_decrease_btn() -> Html {
let config_ctx = use_config();
let increase_font_size = Callback::from(move |_| {
config_ctx.decrease_font_size();
});

html! {
<Tooltip tip={"Increase font size"}>
<btn onclick={increase_font_size} class={HEADER_BTN_CLASSES}>
<MinusIcon />
</btn>
</Tooltip>
}
}
21 changes: 21 additions & 0 deletions frontend/src/components/editor/header/font_increase.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use yew::prelude::*;
use crate::components::editor::header::header::HEADER_BTN_CLASSES;
use crate::contexts::config::use_config;
use crate::components::tooltip::Tooltip;
use crate::icons::PlusIcon;

#[function_component(FontIncreaseBtn)]
pub fn font_increase_btn() -> Html {
let config_ctx = use_config();
let increase_font_size = Callback::from(move |_| {
config_ctx.increase_font_size();
});

html! {
<Tooltip tip={"Increase font size"}>
<btn onclick={increase_font_size} class={HEADER_BTN_CLASSES}>
<PlusIcon />
</btn>
</Tooltip>
}
}
138 changes: 138 additions & 0 deletions frontend/src/components/editor/header/formatting.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use wasm_bindgen::JsCast;
use web_sys::HtmlTextAreaElement;
use yew::prelude::*;
use crate::components::editor::header::header::HEADER_BTN_CLASSES;
use crate::contexts::config::use_config;
use crate::contexts::markdown::{use_markdown, Markdown};
use crate::icons::{BoldIcon, ItalicsIcon, FormatIcon, QuoteIcon};
use gloo::utils::document;

#[function_component(FormattingDropdown)]
pub fn bold_btn() -> Html {
let is_mobile_ui = use_config().is_mobile_ui();
let mut dropdown_classes = classes!("dropdown");
match is_mobile_ui {
true => dropdown_classes.push("dropdown-end"),
false => dropdown_classes.push("dropdown-hover"),
}

html! {
<div class={dropdown_classes}>
<label class={HEADER_BTN_CLASSES} id="add_file_dropdown" tabindex="0" class="btn btn-ghost">
<FormatIcon size={AttrValue::from("24")} />
</label>
<div class="dropdown-content z-[1] menu p-2 shadow bg-base-200 rounded-box w-52 lg:w-max">
<ul tabindex="0">
<BoldBtn />
<ItalicsBtn />
<QuoteBtn />
</ul>
</div>
</div>
}
}

#[function_component(BoldBtn)]
pub fn bold_btn() -> Html {
let md_state = use_markdown();
let bold = Callback::from(move |mouse_event: MouseEvent| {
let text_area: HtmlTextAreaElement = document().get_element_by_id("editor").unwrap().dyn_into().unwrap();
let mut current_value = text_area.value();

if let Some(start) = text_area.selection_start().unwrap() &&
let Some(end) = text_area.selection_end().unwrap() {
let start_usize = start as usize;
let end_usize = end as usize;

current_value.insert_str(start_usize, "**");
current_value.insert_str(end_usize + 2, "**");
text_area.set_selection_end(Some(start + 2));
} else {
current_value.push_str("****");
text_area.set_selection_end(Some(2));
}
let key = md_state.state().key;
let md = Markdown::from(AttrValue::from(current_value), key);
md_state.update_markdown(md);
});

html! {
<li>
<div onclick={bold}>
<BoldIcon />
{"Bold"}
</div>
</li>
}
}

#[function_component(ItalicsBtn)]
pub fn italics_btn() -> Html {
let md_state = use_markdown();
let italics = Callback::from(move |mouse_event: MouseEvent| {
let text_area: HtmlTextAreaElement = document().get_element_by_id("editor").unwrap().dyn_into().unwrap();
let mut current_value = text_area.value();

if let Some(start) = text_area.selection_start().unwrap() &&
let Some(end) = text_area.selection_end().unwrap() {
let start_usize = start as usize;
let end_usize = end as usize;

current_value.insert_str(start_usize, "*");
current_value.insert_str(end_usize + 1, "*");
text_area.set_value(&current_value);
text_area.set_selection_end(Some(start + 1));
} else {
current_value.push_str("**");
text_area.set_value(&current_value);
text_area.set_selection_end(Some(1));
}
let key = md_state.state().key;
let md = Markdown::from(AttrValue::from(current_value), key);
md_state.update_markdown(md);
});

html! {
<li>
<div onclick={italics}>
<ItalicsIcon />
{"Italics"}
</div>
</li>
}
}

#[function_component(QuoteBtn)]
pub fn quote_btn() -> Html {
let md_state = use_markdown();
let quote = Callback::from(move |mouse_event: MouseEvent| {
let text_area: HtmlTextAreaElement = document().get_element_by_id("editor").unwrap().dyn_into().unwrap();
let mut current_value = text_area.value();

if let Some(start) = text_area.selection_start().unwrap() &&
let Some(end) = text_area.selection_end().unwrap() {
let start_usize = start as usize;
let end_usize = end as usize;

current_value.insert_str(start_usize, "> ");
text_area.set_value(&current_value);
text_area.set_selection_end(Some(start + 2));
} else {
current_value.push_str("> ");
text_area.set_value(&current_value);
text_area.set_selection_end(Some(2));
}
let key = md_state.state().key;
let md = Markdown::from(AttrValue::from(current_value), key);
md_state.update_markdown(md);
});

html! {
<li>
<btn onclick={quote}>
<QuoteIcon />
{"Quote"}
</btn>
</li>
}
}
39 changes: 39 additions & 0 deletions frontend/src/components/editor/header/header.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use yew::prelude::*;

use crate::components::editor::header::bold::BoldBtn;
use crate::components::editor::header::formatting::FormattingDropdown;
use crate::components::editor::header::headings::HeadingsDropdown;
use crate::components::editor::header::italics::ItalicsBtn;
use crate::components::editor::header::link::AddLinkBtn;
use crate::components::editor::header::quote::QuoteBtn;
use crate::components::editor::header::redo::RedoBtn;
use crate::components::editor::header::undo::UndoBtn;
use crate::components::editor::header::font_decrease::FontDecreaseBtn;
use crate::components::editor::header::font_increase::FontIncreaseBtn;
use crate::contexts::config::use_config;

pub const HEADER_BTN_CLASSES: &'static str = "btn btn-xs lg:btn-sm btn-ghost px-1.0 lg:px-1.5 xl:px-2.0";


#[function_component(EditorHeader)]
pub fn input_header() -> Html {
let is_mobile_ui = use_config().is_mobile_ui();

html! {
<div class="flex justify-evenly md:justify-end -space-x-0.2 lg:space-x-1">
<UndoBtn />
<RedoBtn />
<HeadingsDropdown />
if is_mobile_ui {
<FormattingDropdown />
} else {
<BoldBtn />
<ItalicsBtn />
<QuoteBtn />
}
<AddLinkBtn />
<FontDecreaseBtn />
<FontIncreaseBtn />
</div>
}
}
Loading

0 comments on commit fff6022

Please sign in to comment.