Introducing Damus Notedeck: a nostr browser
This splits notedeck into: - notedeck - notedeck_chrome - notedeck_columns The `notedeck` crate is the library that `notedeck_chrome` and `notedeck_columns`, use. It contains common functionality related to notedeck apps such as the NoteCache, ImageCache, etc. The `notedeck_chrome` crate is the binary and ui chrome. It is responsible for managing themes, user accounts, signing, data paths, nostrdb, image caches etc. It will eventually have its own ui which has yet to be determined. For now it just manages the browser data, which is passed to apps via a new struct called `AppContext`. `notedeck_columns` is our columns app, with less responsibility now that more things are handled by `notedeck_chrome` There is still much work left to do before this is a proper browser: - process isolation - sandboxing - etc This is the beginning of a new era! We're just getting started. Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
use crate::app_style::NotedeckTextStyle;
|
||||
use crate::key_parsing::AcquireKeyError;
|
||||
use crate::login_manager::AcquireKeyState;
|
||||
use crate::ui::{Preview, PreviewConfig, View};
|
||||
use egui::TextEdit;
|
||||
use egui::{Align, Button, Color32, Frame, InnerResponse, Margin, RichText, Vec2};
|
||||
use enostr::Keypair;
|
||||
use notedeck::NotedeckTextStyle;
|
||||
|
||||
pub struct AccountLoginView<'a> {
|
||||
manager: &'a mut AcquireKeyState,
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
use crate::colors::PINK;
|
||||
use crate::imgcache::ImageCache;
|
||||
use crate::{
|
||||
accounts::Accounts,
|
||||
ui::{Preview, PreviewConfig, View},
|
||||
Damus,
|
||||
};
|
||||
use egui::{
|
||||
Align, Button, Frame, Image, InnerResponse, Layout, RichText, ScrollArea, Ui, UiBuilder, Vec2,
|
||||
};
|
||||
use nostrdb::{Ndb, Transaction};
|
||||
use notedeck::{Accounts, ImageCache};
|
||||
|
||||
use super::profile::preview::SimpleProfilePreview;
|
||||
|
||||
@@ -180,7 +175,7 @@ fn scroll_area() -> ScrollArea {
|
||||
}
|
||||
|
||||
fn add_account_button() -> Button<'static> {
|
||||
let img_data = egui::include_image!("../../assets/icons/add_account_icon_4x.png");
|
||||
let img_data = egui::include_image!("../../../../assets/icons/add_account_icon_4x.png");
|
||||
let img = Image::new(img_data).fit_to_exact_size(Vec2::new(48.0, 48.0));
|
||||
Button::image_and_text(
|
||||
img,
|
||||
@@ -195,48 +190,3 @@ fn add_account_button() -> Button<'static> {
|
||||
fn sign_out_button() -> egui::Button<'static> {
|
||||
egui::Button::new(RichText::new("Sign out"))
|
||||
}
|
||||
|
||||
// PREVIEWS
|
||||
mod preview {
|
||||
|
||||
use super::*;
|
||||
use crate::{accounts::process_accounts_view_response, test_data};
|
||||
|
||||
pub struct AccountsPreview {
|
||||
app: Damus,
|
||||
}
|
||||
|
||||
impl AccountsPreview {
|
||||
fn new() -> Self {
|
||||
let app = test_data::test_app();
|
||||
AccountsPreview { app }
|
||||
}
|
||||
}
|
||||
|
||||
impl View for AccountsPreview {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add_space(24.0);
|
||||
// TODO(jb55): maybe just use render_nav here so we can step through routes
|
||||
if let Some(response) =
|
||||
AccountsView::new(&self.app.ndb, &self.app.accounts, &mut self.app.img_cache)
|
||||
.ui(ui)
|
||||
.inner
|
||||
{
|
||||
process_accounts_view_response(
|
||||
&mut self.app.accounts,
|
||||
&mut self.app.decks_cache,
|
||||
0,
|
||||
response,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Preview for AccountsView<'_> {
|
||||
type Prev = AccountsPreview;
|
||||
|
||||
fn preview(_cfg: PreviewConfig) -> Self::Prev {
|
||||
AccountsPreview::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ use nostrdb::Ndb;
|
||||
use tracing::error;
|
||||
|
||||
use crate::{
|
||||
app_style::{get_font_size, NotedeckTextStyle},
|
||||
login_manager::AcquireKeyState,
|
||||
timeline::{PubkeySource, Timeline, TimelineKind},
|
||||
ui::anim::ICON_EXPANSION_MULTIPLE,
|
||||
user_account::UserAccount,
|
||||
Damus,
|
||||
};
|
||||
|
||||
use notedeck::{AppContext, NotedeckTextStyle, UserAccount};
|
||||
|
||||
use super::{anim::AnimationHelper, padding};
|
||||
|
||||
pub enum AddColumnResponse {
|
||||
@@ -180,8 +180,8 @@ impl<'a> AddColumnView<'a> {
|
||||
let max_width = ui.available_width();
|
||||
let title_style = NotedeckTextStyle::Body;
|
||||
let desc_style = NotedeckTextStyle::Button;
|
||||
let title_min_font_size = get_font_size(ui.ctx(), &title_style);
|
||||
let desc_min_font_size = get_font_size(ui.ctx(), &desc_style);
|
||||
let title_min_font_size = notedeck::fonts::get_font_size(ui.ctx(), &title_style);
|
||||
let desc_min_font_size = notedeck::fonts::get_font_size(ui.ctx(), &desc_style);
|
||||
|
||||
let max_height = {
|
||||
let max_wrap_width =
|
||||
@@ -279,7 +279,7 @@ impl<'a> AddColumnView<'a> {
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Universe",
|
||||
description: "See the whole nostr universe",
|
||||
icon: egui::include_image!("../../assets/icons/universe_icon_dark_4x.png"),
|
||||
icon: egui::include_image!("../../../../assets/icons/universe_icon_dark_4x.png"),
|
||||
option: AddColumnOption::Universe,
|
||||
});
|
||||
|
||||
@@ -293,20 +293,20 @@ impl<'a> AddColumnView<'a> {
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Home timeline",
|
||||
description: "See recommended notes first",
|
||||
icon: egui::include_image!("../../assets/icons/home_icon_dark_4x.png"),
|
||||
icon: egui::include_image!("../../../../assets/icons/home_icon_dark_4x.png"),
|
||||
option: AddColumnOption::Home(source.clone()),
|
||||
});
|
||||
}
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Notifications",
|
||||
description: "Stay up to date with notifications and mentions",
|
||||
icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
icon: egui::include_image!("../../../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
option: AddColumnOption::UndecidedNotification,
|
||||
});
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Hashtag",
|
||||
description: "Stay up to date with a certain hashtag",
|
||||
icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
icon: egui::include_image!("../../../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
option: AddColumnOption::UndecidedHashtag,
|
||||
});
|
||||
|
||||
@@ -326,7 +326,9 @@ impl<'a> AddColumnView<'a> {
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Your Notifications",
|
||||
description: "Stay up to date with your notifications and mentions",
|
||||
icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
icon: egui::include_image!(
|
||||
"../../../../assets/icons/notifications_icon_dark_4x.png"
|
||||
),
|
||||
option: AddColumnOption::Notification(source),
|
||||
});
|
||||
}
|
||||
@@ -334,7 +336,7 @@ impl<'a> AddColumnView<'a> {
|
||||
vec.push(ColumnOptionData {
|
||||
title: "Someone else's Notifications",
|
||||
description: "Stay up to date with someone else's notifications and mentions",
|
||||
icon: egui::include_image!("../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
icon: egui::include_image!("../../../../assets/icons/notifications_icon_dark_4x.png"),
|
||||
option: AddColumnOption::ExternalNotification,
|
||||
});
|
||||
|
||||
@@ -352,19 +354,20 @@ struct ColumnOptionData {
|
||||
pub fn render_add_column_routes(
|
||||
ui: &mut egui::Ui,
|
||||
app: &mut Damus,
|
||||
ctx: &mut AppContext<'_>,
|
||||
col: usize,
|
||||
route: &AddColumnRoute,
|
||||
) {
|
||||
let mut add_column_view = AddColumnView::new(
|
||||
&mut app.view_state.id_state_map,
|
||||
&app.ndb,
|
||||
app.accounts.get_selected_account(),
|
||||
ctx.ndb,
|
||||
ctx.accounts.get_selected_account(),
|
||||
);
|
||||
let resp = match route {
|
||||
AddColumnRoute::Base => add_column_view.ui(ui),
|
||||
AddColumnRoute::UndecidedNotification => add_column_view.notifications_ui(ui),
|
||||
AddColumnRoute::ExternalNotification => add_column_view.external_notification_ui(ui),
|
||||
AddColumnRoute::Hashtag => hashtag_ui(ui, &app.ndb, &mut app.view_state.id_string_map),
|
||||
AddColumnRoute::Hashtag => hashtag_ui(ui, ctx.ndb, &mut app.view_state.id_string_map),
|
||||
};
|
||||
|
||||
if let Some(resp) = resp {
|
||||
@@ -372,27 +375,34 @@ pub fn render_add_column_routes(
|
||||
AddColumnResponse::Timeline(mut timeline) => {
|
||||
crate::timeline::setup_new_timeline(
|
||||
&mut timeline,
|
||||
&app.ndb,
|
||||
ctx.ndb,
|
||||
&mut app.subscriptions,
|
||||
&mut app.pool,
|
||||
&mut app.note_cache,
|
||||
ctx.pool,
|
||||
ctx.note_cache,
|
||||
app.since_optimize,
|
||||
&app.accounts.mutefun(),
|
||||
&ctx.accounts.mutefun(),
|
||||
);
|
||||
app.columns_mut().add_timeline_to_column(col, timeline);
|
||||
app.columns_mut(ctx.accounts)
|
||||
.add_timeline_to_column(col, timeline);
|
||||
}
|
||||
AddColumnResponse::UndecidedNotification => {
|
||||
app.columns_mut().column_mut(col).router_mut().route_to(
|
||||
crate::route::Route::AddColumn(AddColumnRoute::UndecidedNotification),
|
||||
);
|
||||
app.columns_mut(ctx.accounts)
|
||||
.column_mut(col)
|
||||
.router_mut()
|
||||
.route_to(crate::route::Route::AddColumn(
|
||||
AddColumnRoute::UndecidedNotification,
|
||||
));
|
||||
}
|
||||
AddColumnResponse::ExternalNotification => {
|
||||
app.columns_mut().column_mut(col).router_mut().route_to(
|
||||
crate::route::Route::AddColumn(AddColumnRoute::ExternalNotification),
|
||||
);
|
||||
app.columns_mut(ctx.accounts)
|
||||
.column_mut(col)
|
||||
.router_mut()
|
||||
.route_to(crate::route::Route::AddColumn(
|
||||
AddColumnRoute::ExternalNotification,
|
||||
));
|
||||
}
|
||||
AddColumnResponse::Hashtag => {
|
||||
app.columns_mut()
|
||||
app.columns_mut(ctx.accounts)
|
||||
.column_mut(col)
|
||||
.router_mut()
|
||||
.route_to(crate::route::Route::AddColumn(AddColumnRoute::Hashtag));
|
||||
@@ -438,44 +448,3 @@ pub fn hashtag_ui(
|
||||
})
|
||||
.inner
|
||||
}
|
||||
|
||||
mod preview {
|
||||
use crate::{
|
||||
test_data,
|
||||
ui::{Preview, PreviewConfig, View},
|
||||
Damus,
|
||||
};
|
||||
|
||||
use super::AddColumnView;
|
||||
|
||||
pub struct AddColumnPreview {
|
||||
app: Damus,
|
||||
}
|
||||
|
||||
impl AddColumnPreview {
|
||||
fn new() -> Self {
|
||||
let app = test_data::test_app();
|
||||
|
||||
AddColumnPreview { app }
|
||||
}
|
||||
}
|
||||
|
||||
impl View for AddColumnPreview {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
AddColumnView::new(
|
||||
&mut self.app.view_state.id_state_map,
|
||||
&self.app.ndb,
|
||||
self.app.accounts.get_selected_account(),
|
||||
)
|
||||
.ui(ui);
|
||||
}
|
||||
}
|
||||
|
||||
impl Preview for AddColumnView<'_> {
|
||||
type Prev = AddColumnPreview;
|
||||
|
||||
fn preview(_cfg: PreviewConfig) -> Self::Prev {
|
||||
AddColumnPreview::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use crate::{
|
||||
app_style::NotedeckTextStyle,
|
||||
column::Columns,
|
||||
imgcache::ImageCache,
|
||||
nav::RenderNavAction,
|
||||
route::Route,
|
||||
timeline::{TimelineId, TimelineRoute},
|
||||
@@ -14,6 +12,7 @@ use crate::{
|
||||
use egui::{RichText, Stroke, UiBuilder};
|
||||
use enostr::Pubkey;
|
||||
use nostrdb::{Ndb, Transaction};
|
||||
use notedeck::{ImageCache, NotedeckTextStyle};
|
||||
|
||||
pub struct NavTitle<'a> {
|
||||
ndb: &'a Ndb,
|
||||
@@ -124,9 +123,9 @@ impl<'a> NavTitle<'a> {
|
||||
let max_size = icon_width * ICON_EXPANSION_MULTIPLE;
|
||||
|
||||
let img_data = if ui.visuals().dark_mode {
|
||||
egui::include_image!("../../../assets/icons/column_delete_icon_4x.png")
|
||||
egui::include_image!("../../../../../assets/icons/column_delete_icon_4x.png")
|
||||
} else {
|
||||
egui::include_image!("../../../assets/icons/column_delete_icon_light_4x.png")
|
||||
egui::include_image!("../../../../../assets/icons/column_delete_icon_light_4x.png")
|
||||
};
|
||||
let img = egui::Image::new(img_data).max_width(img_size);
|
||||
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
use crate::{app_style::deck_icon_font_sized, colors::PINK, deck_state::DeckState};
|
||||
use egui::{vec2, Button, Color32, Label, RichText, Stroke, Ui, Widget};
|
||||
|
||||
use crate::{
|
||||
app_style::{deck_icon_font_sized, get_font_size, NotedeckTextStyle},
|
||||
colors::PINK,
|
||||
deck_state::DeckState,
|
||||
fonts::NamedFontFamily,
|
||||
};
|
||||
use notedeck::{NamedFontFamily, NotedeckTextStyle};
|
||||
|
||||
use super::{
|
||||
anim::{AnimationHelper, ICON_EXPANSION_MULTIPLE},
|
||||
@@ -39,7 +34,7 @@ impl<'a> ConfigureDeckView<'a> {
|
||||
|
||||
pub fn ui(&mut self, ui: &mut Ui) -> Option<ConfigureDeckResponse> {
|
||||
let title_font = egui::FontId::new(
|
||||
get_font_size(ui.ctx(), &NotedeckTextStyle::Heading4),
|
||||
notedeck::fonts::get_font_size(ui.ctx(), &NotedeckTextStyle::Heading4),
|
||||
egui::FontFamily::Name(NamedFontFamily::Bold.as_str().into()),
|
||||
);
|
||||
padding(16.0, ui, |ui| {
|
||||
@@ -52,7 +47,10 @@ impl<'a> ConfigureDeckView<'a> {
|
||||
ui.add(Label::new(
|
||||
RichText::new("We recommend short names")
|
||||
.color(ui.visuals().noninteractive().fg_stroke.color)
|
||||
.size(get_font_size(ui.ctx(), &NotedeckTextStyle::Small)),
|
||||
.size(notedeck::fonts::get_font_size(
|
||||
ui.ctx(),
|
||||
&NotedeckTextStyle::Small,
|
||||
)),
|
||||
));
|
||||
|
||||
ui.add_space(32.0);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::{colors, imgcache::ImageCache, ui};
|
||||
use crate::ui;
|
||||
use nostrdb::{Ndb, Transaction};
|
||||
use notedeck::ImageCache;
|
||||
|
||||
pub struct Mention<'a> {
|
||||
ndb: &'a Ndb,
|
||||
@@ -66,6 +67,8 @@ fn mention_ui(
|
||||
#[cfg(feature = "profiling")]
|
||||
puffin::profile_function!();
|
||||
|
||||
let link_color = ui.visuals().hyperlink_color;
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
let profile = ndb.get_profile_by_pubkey(txn, pk).ok();
|
||||
|
||||
@@ -77,7 +80,7 @@ fn mention_ui(
|
||||
};
|
||||
|
||||
let resp = ui.add(
|
||||
egui::Label::new(egui::RichText::new(name).color(colors::PURPLE).size(size))
|
||||
egui::Label::new(egui::RichText::new(name).color(link_color).size(size))
|
||||
.selectable(selectable),
|
||||
);
|
||||
|
||||
|
||||
@@ -59,28 +59,3 @@ pub fn hline(ui: &egui::Ui) {
|
||||
let stroke = ui.style().visuals.widgets.noninteractive.bg_stroke;
|
||||
ui.painter().hline(rect.x_range(), resize_y, stroke);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(unreachable_code)]
|
||||
pub fn is_compiled_as_mobile() -> bool {
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
{
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
{
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Determine if the screen is narrow. This is useful for detecting mobile
|
||||
/// contexts, but with the nuance that we may also have a wide android tablet.
|
||||
pub fn is_narrow(ctx: &egui::Context) -> bool {
|
||||
let screen_size = ctx.input(|c| c.screen_rect().size());
|
||||
screen_size.x < 550.0
|
||||
}
|
||||
|
||||
pub fn is_oled() -> bool {
|
||||
is_compiled_as_mobile()
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use crate::actionbar::NoteAction;
|
||||
use crate::images::ImageType;
|
||||
use crate::imgcache::ImageCache;
|
||||
use crate::notecache::NoteCache;
|
||||
use crate::ui;
|
||||
use crate::ui::note::{NoteOptions, NoteResponse};
|
||||
use crate::ui::ProfilePic;
|
||||
use crate::{colors, ui};
|
||||
use egui::{Color32, Hyperlink, Image, RichText};
|
||||
use nostrdb::{BlockType, Mention, Ndb, Note, NoteKey, Transaction};
|
||||
use tracing::warn;
|
||||
|
||||
use notedeck::{ImageCache, NoteCache};
|
||||
|
||||
pub struct NoteContents<'a> {
|
||||
ndb: &'a Ndb,
|
||||
img_cache: &'a mut ImageCache,
|
||||
@@ -94,8 +94,8 @@ pub fn render_note_preview(
|
||||
return ui
|
||||
.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 0.0;
|
||||
ui.colored_label(colors::PURPLE, "@");
|
||||
ui.colored_label(colors::PURPLE, &id_str[4..16]);
|
||||
ui.colored_label(link_color, "@");
|
||||
ui.colored_label(link_color, &id_str[4..16]);
|
||||
})
|
||||
.response;
|
||||
*/
|
||||
@@ -145,6 +145,7 @@ fn render_note_contents(
|
||||
let mut images: Vec<String> = vec![];
|
||||
let mut inline_note: Option<(&[u8; 32], &str)> = None;
|
||||
let hide_media = options.has_hide_media();
|
||||
let link_color = ui.visuals().hyperlink_color;
|
||||
|
||||
let response = ui.horizontal_wrapped(|ui| {
|
||||
let blocks = if let Ok(blocks) = ndb.get_blocks_by_key(txn, note_key) {
|
||||
@@ -177,14 +178,14 @@ fn render_note_contents(
|
||||
}
|
||||
|
||||
_ => {
|
||||
ui.colored_label(colors::PURPLE, format!("@{}", &block.as_str()[4..16]));
|
||||
ui.colored_label(link_color, format!("@{}", &block.as_str()[4..16]));
|
||||
}
|
||||
},
|
||||
|
||||
BlockType::Hashtag => {
|
||||
#[cfg(feature = "profiling")]
|
||||
puffin::profile_scope!("hashtag contents");
|
||||
ui.colored_label(colors::PURPLE, format!("#{}", block.as_str()));
|
||||
ui.colored_label(link_color, format!("#{}", block.as_str()));
|
||||
}
|
||||
|
||||
BlockType::Url => {
|
||||
@@ -195,7 +196,7 @@ fn render_note_contents(
|
||||
#[cfg(feature = "profiling")]
|
||||
puffin::profile_scope!("url contents");
|
||||
ui.add(Hyperlink::from_label_and_url(
|
||||
RichText::new(block.as_str()).color(colors::PURPLE),
|
||||
RichText::new(block.as_str()).color(link_color),
|
||||
block.as_str(),
|
||||
));
|
||||
}
|
||||
@@ -208,7 +209,7 @@ fn render_note_contents(
|
||||
}
|
||||
|
||||
_ => {
|
||||
ui.colored_label(colors::PURPLE, block.as_str());
|
||||
ui.colored_label(link_color, block.as_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use crate::colors;
|
||||
use egui::{Rect, Vec2};
|
||||
use enostr::{NoteId, Pubkey};
|
||||
use nostrdb::{Note, NoteKey};
|
||||
@@ -136,7 +135,7 @@ impl NoteContextButton {
|
||||
let translated_radius = (cur_radius - 1.0) / 2.0;
|
||||
|
||||
// This works in both themes
|
||||
let color = colors::GRAY_SECONDARY;
|
||||
let color = ui.style().visuals.noninteractive().fg_stroke.color;
|
||||
|
||||
// Draw circles
|
||||
let painter = ui.painter_at(put_at);
|
||||
|
||||
@@ -14,16 +14,14 @@ pub use reply::PostReplyView;
|
||||
|
||||
use crate::{
|
||||
actionbar::NoteAction,
|
||||
app_style::NotedeckTextStyle,
|
||||
colors,
|
||||
imgcache::ImageCache,
|
||||
notecache::{CachedNote, NoteCache},
|
||||
ui::{self, View},
|
||||
};
|
||||
|
||||
use egui::emath::{pos2, Vec2};
|
||||
use egui::{Id, Label, Pos2, Rect, Response, RichText, Sense};
|
||||
use enostr::{NoteId, Pubkey};
|
||||
use nostrdb::{Ndb, Note, NoteKey, NoteReply, Transaction};
|
||||
use notedeck::{CachedNote, ImageCache, NoteCache, NotedeckTextStyle};
|
||||
|
||||
use super::profile::preview::{get_display_name, one_line_display_name_widget};
|
||||
|
||||
@@ -80,15 +78,9 @@ fn reply_desc(
|
||||
|
||||
let size = 10.0;
|
||||
let selectable = false;
|
||||
let color = ui.style().visuals.noninteractive().fg_stroke.color;
|
||||
|
||||
ui.add(
|
||||
Label::new(
|
||||
RichText::new("replying to")
|
||||
.size(size)
|
||||
.color(colors::GRAY_SECONDARY),
|
||||
)
|
||||
.selectable(selectable),
|
||||
);
|
||||
ui.add(Label::new(RichText::new("replying to").size(size).color(color)).selectable(selectable));
|
||||
|
||||
let reply = if let Some(reply) = note_reply.reply() {
|
||||
reply
|
||||
@@ -99,14 +91,7 @@ fn reply_desc(
|
||||
let reply_note = if let Ok(reply_note) = ndb.get_note_by_id(txn, reply.id) {
|
||||
reply_note
|
||||
} else {
|
||||
ui.add(
|
||||
Label::new(
|
||||
RichText::new("a note")
|
||||
.size(size)
|
||||
.color(colors::GRAY_SECONDARY),
|
||||
)
|
||||
.selectable(selectable),
|
||||
);
|
||||
ui.add(Label::new(RichText::new("a note").size(size).color(color)).selectable(selectable));
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -117,14 +102,7 @@ fn reply_desc(
|
||||
.size(size)
|
||||
.selectable(selectable),
|
||||
);
|
||||
ui.add(
|
||||
Label::new(
|
||||
RichText::new("'s note")
|
||||
.size(size)
|
||||
.color(colors::GRAY_SECONDARY),
|
||||
)
|
||||
.selectable(selectable),
|
||||
);
|
||||
ui.add(Label::new(RichText::new("'s note").size(size).color(color)).selectable(selectable));
|
||||
} else if let Some(root) = note_reply.root() {
|
||||
// replying to another post in a thread, not the root
|
||||
|
||||
@@ -137,12 +115,8 @@ fn reply_desc(
|
||||
.selectable(selectable),
|
||||
);
|
||||
ui.add(
|
||||
Label::new(
|
||||
RichText::new("'s note")
|
||||
.size(size)
|
||||
.color(colors::GRAY_SECONDARY),
|
||||
)
|
||||
.selectable(selectable),
|
||||
Label::new(RichText::new("'s note").size(size).color(color))
|
||||
.selectable(selectable),
|
||||
);
|
||||
} else {
|
||||
// replying to bob in alice's thread
|
||||
@@ -153,8 +127,7 @@ fn reply_desc(
|
||||
.selectable(selectable),
|
||||
);
|
||||
ui.add(
|
||||
Label::new(RichText::new("in").size(size).color(colors::GRAY_SECONDARY))
|
||||
.selectable(selectable),
|
||||
Label::new(RichText::new("in").size(size).color(color)).selectable(selectable),
|
||||
);
|
||||
ui.add(
|
||||
ui::Mention::new(ndb, img_cache, txn, root_note.pubkey())
|
||||
@@ -162,12 +135,8 @@ fn reply_desc(
|
||||
.selectable(selectable),
|
||||
);
|
||||
ui.add(
|
||||
Label::new(
|
||||
RichText::new("'s thread")
|
||||
.size(size)
|
||||
.color(colors::GRAY_SECONDARY),
|
||||
)
|
||||
.selectable(selectable),
|
||||
Label::new(RichText::new("'s thread").size(size).color(color))
|
||||
.selectable(selectable),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -177,12 +146,8 @@ fn reply_desc(
|
||||
.selectable(selectable),
|
||||
);
|
||||
ui.add(
|
||||
Label::new(
|
||||
RichText::new("in someone's thread")
|
||||
.size(size)
|
||||
.color(colors::GRAY_SECONDARY),
|
||||
)
|
||||
.selectable(selectable),
|
||||
Label::new(RichText::new("in someone's thread").size(size).color(color))
|
||||
.selectable(selectable),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -382,6 +347,7 @@ impl<'a> NoteView<'a> {
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
let resp = ui.add(one_line_display_name_widget(
|
||||
ui.visuals(),
|
||||
get_display_name(profile.as_ref().ok()),
|
||||
style,
|
||||
));
|
||||
@@ -391,10 +357,11 @@ impl<'a> NoteView<'a> {
|
||||
ui.add(ui::ProfilePreview::new(rec, self.img_cache));
|
||||
});
|
||||
}
|
||||
let color = ui.style().visuals.noninteractive().fg_stroke.color;
|
||||
ui.add_space(4.0);
|
||||
ui.label(
|
||||
RichText::new("Reposted")
|
||||
.color(colors::GRAY_SECONDARY)
|
||||
.color(color)
|
||||
.text_style(style.text_style()),
|
||||
);
|
||||
});
|
||||
@@ -690,9 +657,8 @@ fn render_note_actionbar(
|
||||
}
|
||||
|
||||
fn secondary_label(ui: &mut egui::Ui, s: impl Into<String>) {
|
||||
ui.add(Label::new(
|
||||
RichText::new(s).size(10.0).color(colors::GRAY_SECONDARY),
|
||||
));
|
||||
let color = ui.style().visuals.noninteractive().fg_stroke.color;
|
||||
ui.add(Label::new(RichText::new(s).size(10.0).color(color)));
|
||||
}
|
||||
|
||||
fn render_reltime(
|
||||
@@ -718,9 +684,9 @@ fn render_reltime(
|
||||
|
||||
fn reply_button(ui: &mut egui::Ui, note_key: NoteKey) -> egui::Response {
|
||||
let img_data = if ui.style().visuals.dark_mode {
|
||||
egui::include_image!("../../../assets/icons/reply.png")
|
||||
egui::include_image!("../../../../../assets/icons/reply.png")
|
||||
} else {
|
||||
egui::include_image!("../../../assets/icons/reply-dark.png")
|
||||
egui::include_image!("../../../../../assets/icons/reply-dark.png")
|
||||
};
|
||||
|
||||
let (rect, size, resp) =
|
||||
@@ -737,9 +703,9 @@ fn reply_button(ui: &mut egui::Ui, note_key: NoteKey) -> egui::Response {
|
||||
|
||||
fn repost_icon(dark_mode: bool) -> egui::Image<'static> {
|
||||
let img_data = if dark_mode {
|
||||
egui::include_image!("../../../assets/icons/repost_icon_4x.png")
|
||||
egui::include_image!("../../../../../assets/icons/repost_icon_4x.png")
|
||||
} else {
|
||||
egui::include_image!("../../../assets/icons/repost_light_4x.png")
|
||||
egui::include_image!("../../../../../assets/icons/repost_light_4x.png")
|
||||
};
|
||||
egui::Image::new(img_data)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use crate::draft::{Draft, Drafts};
|
||||
use crate::imgcache::ImageCache;
|
||||
use crate::notecache::NoteCache;
|
||||
use crate::post::NewPost;
|
||||
use crate::ui::{self, Preview, PreviewConfig, View};
|
||||
use crate::Result;
|
||||
@@ -10,6 +8,8 @@ use enostr::{FilledKeypair, FullKeypair, NoteId, RelayPool};
|
||||
use nostrdb::{Config, Ndb, Transaction};
|
||||
use tracing::info;
|
||||
|
||||
use notedeck::{ImageCache, NoteCache};
|
||||
|
||||
use super::contents::render_note_preview;
|
||||
|
||||
pub struct PostView<'a> {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use enostr::{FilledKeypair, NoteId};
|
||||
use nostrdb::Ndb;
|
||||
use notedeck::{ImageCache, NoteCache};
|
||||
|
||||
use crate::{draft::Draft, imgcache::ImageCache, notecache::NoteCache, ui};
|
||||
use crate::{draft::Draft, ui};
|
||||
|
||||
use super::{PostResponse, PostType};
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use crate::draft::Draft;
|
||||
use crate::imgcache::ImageCache;
|
||||
use crate::notecache::NoteCache;
|
||||
use crate::ui;
|
||||
use crate::ui::note::{PostResponse, PostType};
|
||||
use enostr::{FilledKeypair, NoteId};
|
||||
use nostrdb::Ndb;
|
||||
|
||||
use notedeck::{ImageCache, NoteCache};
|
||||
|
||||
pub struct PostReplyView<'a> {
|
||||
ndb: &'a Ndb,
|
||||
poster: FilledKeypair<'a>,
|
||||
|
||||
@@ -8,12 +8,10 @@ use nostrdb::{Ndb, Transaction};
|
||||
pub use picture::ProfilePic;
|
||||
pub use preview::ProfilePreview;
|
||||
|
||||
use crate::{
|
||||
actionbar::NoteAction, imgcache::ImageCache, muted::MuteFun, notecache::NoteCache,
|
||||
notes_holder::NotesHolderStorage, profile::Profile,
|
||||
};
|
||||
use crate::{actionbar::NoteAction, notes_holder::NotesHolderStorage, profile::Profile};
|
||||
|
||||
use super::timeline::{tabs_ui, TimelineTabView};
|
||||
use notedeck::{ImageCache, MuteFun, NoteCache};
|
||||
|
||||
pub struct ProfileView<'a> {
|
||||
pubkey: &'a Pubkey,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use crate::images::ImageType;
|
||||
use crate::imgcache::ImageCache;
|
||||
use crate::ui::{Preview, PreviewConfig, View};
|
||||
use egui::{vec2, Sense, TextureHandle};
|
||||
use nostrdb::{Ndb, Transaction};
|
||||
|
||||
use notedeck::ImageCache;
|
||||
|
||||
pub struct ProfilePic<'cache, 'url> {
|
||||
cache: &'cache mut ImageCache,
|
||||
url: &'url str,
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
use crate::app_style::{get_font_size, NotedeckTextStyle};
|
||||
use crate::imgcache::ImageCache;
|
||||
use crate::storage::{DataPath, DataPathType};
|
||||
use crate::ui::ProfilePic;
|
||||
use crate::user_account::UserAccount;
|
||||
use crate::{colors, images, DisplayName};
|
||||
use egui::load::TexturePoll;
|
||||
use egui::{Frame, Label, RichText, Sense, Widget};
|
||||
@@ -10,6 +6,8 @@ use egui_extras::Size;
|
||||
use enostr::{NoteId, Pubkey};
|
||||
use nostrdb::{Ndb, ProfileRecord, Transaction};
|
||||
|
||||
use notedeck::{DataPath, DataPathType, ImageCache, NotedeckTextStyle, UserAccount};
|
||||
|
||||
pub struct ProfilePreview<'a, 'cache> {
|
||||
profile: &'a ProfileRecord<'a>,
|
||||
cache: &'cache mut ImageCache,
|
||||
@@ -121,7 +119,10 @@ impl egui::Widget for SimpleProfilePreview<'_, '_> {
|
||||
ui.add(
|
||||
Label::new(
|
||||
RichText::new("Read only")
|
||||
.size(get_font_size(ui.ctx(), &NotedeckTextStyle::Tiny))
|
||||
.size(notedeck::fonts::get_font_size(
|
||||
ui.ctx(),
|
||||
&NotedeckTextStyle::Tiny,
|
||||
))
|
||||
.color(ui.visuals().warn_fg_color),
|
||||
)
|
||||
.selectable(false),
|
||||
@@ -256,17 +257,16 @@ fn display_name_widget(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn one_line_display_name_widget(
|
||||
display_name: DisplayName<'_>,
|
||||
pub fn one_line_display_name_widget<'a>(
|
||||
visuals: &egui::Visuals,
|
||||
display_name: DisplayName<'a>,
|
||||
style: NotedeckTextStyle,
|
||||
) -> impl egui::Widget + '_ {
|
||||
) -> impl egui::Widget + 'a {
|
||||
let text_style = style.text_style();
|
||||
let color = visuals.noninteractive().fg_stroke.color;
|
||||
|
||||
move |ui: &mut egui::Ui| match display_name {
|
||||
DisplayName::One(n) => ui.label(
|
||||
RichText::new(n)
|
||||
.text_style(text_style)
|
||||
.color(colors::GRAY_SECONDARY),
|
||||
),
|
||||
DisplayName::One(n) => ui.label(RichText::new(n).text_style(text_style).color(color)),
|
||||
|
||||
DisplayName::Both {
|
||||
display_name,
|
||||
@@ -274,7 +274,7 @@ pub fn one_line_display_name_widget(
|
||||
} => ui.label(
|
||||
RichText::new(display_name)
|
||||
.text_style(text_style)
|
||||
.color(colors::GRAY_SECONDARY),
|
||||
.color(color),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ use crate::relay_pool_manager::{RelayPoolManager, RelayStatus};
|
||||
use crate::ui::{Preview, PreviewConfig, View};
|
||||
use egui::{Align, Button, Frame, Layout, Margin, Rgba, RichText, Rounding, Ui, Vec2};
|
||||
|
||||
use crate::app_style::NotedeckTextStyle;
|
||||
use enostr::RelayPool;
|
||||
use notedeck::NotedeckTextStyle;
|
||||
|
||||
pub struct RelayView<'a> {
|
||||
manager: RelayPoolManager<'a>,
|
||||
@@ -126,7 +126,7 @@ fn delete_button(_dark_mode: bool) -> egui::Button<'static> {
|
||||
egui::include_image!("../../assets/icons/delete_icon_4x.png")
|
||||
};
|
||||
*/
|
||||
let img_data = egui::include_image!("../../assets/icons/delete_icon_4x.png");
|
||||
let img_data = egui::include_image!("../../../../assets/icons/delete_icon_4x.png");
|
||||
|
||||
egui::Button::image(egui::Image::new(img_data).max_width(10.0)).frame(false)
|
||||
}
|
||||
@@ -165,12 +165,14 @@ fn show_connection_status(ui: &mut Ui, status: &RelayStatus) {
|
||||
|
||||
fn get_connection_icon(status: &RelayStatus) -> egui::Image<'static> {
|
||||
let img_data = match status {
|
||||
RelayStatus::Connected => egui::include_image!("../../assets/icons/connected_icon_4x.png"),
|
||||
RelayStatus::Connected => {
|
||||
egui::include_image!("../../../../assets/icons/connected_icon_4x.png")
|
||||
}
|
||||
RelayStatus::Connecting => {
|
||||
egui::include_image!("../../assets/icons/connecting_icon_4x.png")
|
||||
egui::include_image!("../../../../assets/icons/connecting_icon_4x.png")
|
||||
}
|
||||
RelayStatus::Disconnected => {
|
||||
egui::include_image!("../../assets/icons/disconnected_icon_4x.png")
|
||||
egui::include_image!("../../../../assets/icons/disconnected_icon_4x.png")
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -5,21 +5,18 @@ use egui::{
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::{
|
||||
accounts::{Accounts, AccountsRoute},
|
||||
accounts::AccountsRoute,
|
||||
app::{get_active_columns_mut, get_decks_mut},
|
||||
app_style::DECK_ICON_SIZE,
|
||||
colors,
|
||||
column::Column,
|
||||
decks::{DecksAction, DecksCache},
|
||||
imgcache::ImageCache,
|
||||
nav::SwitchingAction,
|
||||
route::Route,
|
||||
support::Support,
|
||||
theme_handler::ThemeHandler,
|
||||
user_account::UserAccount,
|
||||
Damus,
|
||||
};
|
||||
|
||||
use notedeck::{Accounts, ImageCache, NotedeckTextStyle, ThemeHandler, UserAccount};
|
||||
|
||||
use super::{
|
||||
anim::{AnimationHelper, ICON_EXPANSION_MULTIPLE},
|
||||
configure_deck::deck_icon,
|
||||
@@ -386,9 +383,9 @@ fn settings_button(dark_mode: bool) -> impl Widget {
|
||||
let img_size = 24.0;
|
||||
let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget
|
||||
let img_data = if dark_mode {
|
||||
egui::include_image!("../../assets/icons/settings_dark_4x.png")
|
||||
egui::include_image!("../../../../assets/icons/settings_dark_4x.png")
|
||||
} else {
|
||||
egui::include_image!("../../assets/icons/settings_light_4x.png")
|
||||
egui::include_image!("../../../../assets/icons/settings_light_4x.png")
|
||||
};
|
||||
let img = egui::Image::new(img_data).max_width(img_size);
|
||||
|
||||
@@ -412,9 +409,9 @@ fn add_column_button(dark_mode: bool) -> impl Widget {
|
||||
let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget
|
||||
|
||||
let img_data = if dark_mode {
|
||||
egui::include_image!("../../assets/icons/add_column_dark_4x.png")
|
||||
egui::include_image!("../../../../assets/icons/add_column_dark_4x.png")
|
||||
} else {
|
||||
egui::include_image!("../../assets/icons/add_column_light_4x.png")
|
||||
egui::include_image!("../../../../assets/icons/add_column_light_4x.png")
|
||||
};
|
||||
|
||||
let img = egui::Image::new(img_data).max_width(img_size);
|
||||
@@ -531,7 +528,7 @@ fn search_button() -> impl Widget {
|
||||
fn expand_side_panel_button() -> impl Widget {
|
||||
|ui: &mut egui::Ui| -> egui::Response {
|
||||
let img_size = 40.0;
|
||||
let img_data = egui::include_image!("../../assets/damus_rounded_80.png");
|
||||
let img_data = egui::include_image!("../../../../assets/damus_rounded_80.png");
|
||||
let img = egui::Image::new(img_data).max_width(img_size);
|
||||
|
||||
ui.add(img)
|
||||
@@ -544,9 +541,9 @@ fn support_button() -> impl Widget {
|
||||
|
||||
let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget
|
||||
let img_data = if ui.visuals().dark_mode {
|
||||
egui::include_image!("../../assets/icons/help_icon_dark_4x.png")
|
||||
egui::include_image!("../../../../assets/icons/help_icon_dark_4x.png")
|
||||
} else {
|
||||
egui::include_image!("../../assets/icons/help_icon_inverted_4x.png")
|
||||
egui::include_image!("../../../../assets/icons/help_icon_inverted_4x.png")
|
||||
};
|
||||
let img = egui::Image::new(img_data).max_width(img_size);
|
||||
|
||||
@@ -569,7 +566,7 @@ fn add_deck_button() -> impl Widget {
|
||||
let img_size = 40.0;
|
||||
|
||||
let max_size = ICON_WIDTH * ICON_EXPANSION_MULTIPLE; // max size of the widget
|
||||
let img_data = egui::include_image!("../../assets/icons/new_deck_icon_4x_dark.png");
|
||||
let img_data = egui::include_image!("../../../../assets/icons/new_deck_icon_4x_dark.png");
|
||||
let img = egui::Image::new(img_data).max_width(img_size);
|
||||
|
||||
let helper = AnimationHelper::new(ui, "new-deck-icon", vec2(max_size, max_size));
|
||||
@@ -626,80 +623,18 @@ fn milestone_name() -> impl Widget {
|
||||
|ui: &mut egui::Ui| -> egui::Response {
|
||||
ui.vertical_centered(|ui| {
|
||||
let font = egui::FontId::new(
|
||||
crate::app_style::get_font_size(
|
||||
notedeck::fonts::get_font_size(
|
||||
ui.ctx(),
|
||||
&crate::app_style::NotedeckTextStyle::Tiny,
|
||||
&NotedeckTextStyle::Tiny,
|
||||
),
|
||||
egui::FontFamily::Name(crate::fonts::NamedFontFamily::Bold.as_str().into()),
|
||||
egui::FontFamily::Name(notedeck::fonts::NamedFontFamily::Bold.as_str().into()),
|
||||
);
|
||||
ui.add(Label::new(
|
||||
RichText::new("ALPHA")
|
||||
.color(crate::colors::GRAY_SECONDARY)
|
||||
.color( ui.style().visuals.noninteractive().fg_stroke.color)
|
||||
.font(font),
|
||||
).selectable(false)).on_hover_text("Notedeck is an alpha product. Expect bugs and contact us when you run into issues.").on_hover_cursor(egui::CursorIcon::Help)
|
||||
})
|
||||
.inner
|
||||
}
|
||||
}
|
||||
|
||||
mod preview {
|
||||
|
||||
use egui_extras::{Size, StripBuilder};
|
||||
|
||||
use crate::{
|
||||
app::get_active_columns_mut,
|
||||
test_data,
|
||||
ui::{Preview, PreviewConfig},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub struct DesktopSidePanelPreview {
|
||||
app: Damus,
|
||||
}
|
||||
|
||||
impl DesktopSidePanelPreview {
|
||||
fn new() -> Self {
|
||||
let mut app = test_data::test_app();
|
||||
get_active_columns_mut(&app.accounts, &mut app.decks_cache)
|
||||
.add_column(Column::new(vec![Route::accounts()]));
|
||||
DesktopSidePanelPreview { app }
|
||||
}
|
||||
}
|
||||
|
||||
impl View for DesktopSidePanelPreview {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
StripBuilder::new(ui)
|
||||
.size(Size::exact(SIDE_PANEL_WIDTH))
|
||||
.sizes(Size::remainder(), 0)
|
||||
.clip(true)
|
||||
.horizontal(|mut strip| {
|
||||
strip.cell(|ui| {
|
||||
let mut panel = DesktopSidePanel::new(
|
||||
&self.app.ndb,
|
||||
&mut self.app.img_cache,
|
||||
self.app.accounts.get_selected_account(),
|
||||
&self.app.decks_cache,
|
||||
);
|
||||
let response = panel.show(ui);
|
||||
|
||||
DesktopSidePanel::perform_action(
|
||||
&mut self.app.decks_cache,
|
||||
&self.app.accounts,
|
||||
&mut self.app.support,
|
||||
&mut self.app.theme,
|
||||
response.action,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Preview for DesktopSidePanel<'_> {
|
||||
type Prev = DesktopSidePanelPreview;
|
||||
|
||||
fn preview(_cfg: PreviewConfig) -> Self::Prev {
|
||||
DesktopSidePanelPreview::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
use egui::{vec2, Button, Label, Layout, RichText};
|
||||
use tracing::error;
|
||||
|
||||
use crate::{
|
||||
app_style::{get_font_size, NotedeckTextStyle},
|
||||
colors::PINK,
|
||||
fonts::NamedFontFamily,
|
||||
support::Support,
|
||||
};
|
||||
use crate::{colors::PINK, support::Support};
|
||||
|
||||
use super::padding;
|
||||
use notedeck::{NamedFontFamily, NotedeckTextStyle};
|
||||
|
||||
pub struct SupportView<'a> {
|
||||
support: &'a mut Support,
|
||||
@@ -23,7 +19,7 @@ impl<'a> SupportView<'a> {
|
||||
padding(8.0, ui, |ui| {
|
||||
ui.spacing_mut().item_spacing = egui::vec2(0.0, 8.0);
|
||||
let font = egui::FontId::new(
|
||||
get_font_size(ui.ctx(), &NotedeckTextStyle::Body),
|
||||
notedeck::fonts::get_font_size(ui.ctx(), &NotedeckTextStyle::Body),
|
||||
egui::FontFamily::Name(NamedFontFamily::Bold.as_str().into()),
|
||||
);
|
||||
ui.add(Label::new(RichText::new("Running into a bug?").font(font)));
|
||||
@@ -32,7 +28,8 @@ impl<'a> SupportView<'a> {
|
||||
ui.label("Open your default email client to get help from the Damus team");
|
||||
let size = vec2(120.0, 40.0);
|
||||
ui.allocate_ui_with_layout(size, Layout::top_down(egui::Align::Center), |ui| {
|
||||
let font_size = get_font_size(ui.ctx(), &NotedeckTextStyle::Body);
|
||||
let font_size =
|
||||
notedeck::fonts::get_font_size(ui.ctx(), &NotedeckTextStyle::Body);
|
||||
let button_resp = ui.add(open_email_button(font_size, size));
|
||||
if button_resp.clicked() {
|
||||
if let Err(e) = open::that(self.support.get_mailto_url()) {
|
||||
@@ -54,9 +51,9 @@ impl<'a> SupportView<'a> {
|
||||
RichText::new("Step 2").text_style(NotedeckTextStyle::Heading3.text_style()),
|
||||
);
|
||||
let size = vec2(80.0, 40.0);
|
||||
let copy_button = Button::new(
|
||||
RichText::new("Copy").size(get_font_size(ui.ctx(), &NotedeckTextStyle::Body)),
|
||||
)
|
||||
let copy_button = Button::new(RichText::new("Copy").size(
|
||||
notedeck::fonts::get_font_size(ui.ctx(), &NotedeckTextStyle::Body),
|
||||
))
|
||||
.fill(PINK)
|
||||
.min_size(size);
|
||||
padding(8.0, ui, |ui| {
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
use crate::{
|
||||
actionbar::NoteAction,
|
||||
imgcache::ImageCache,
|
||||
muted::MuteFun,
|
||||
notecache::NoteCache,
|
||||
notes_holder::{NotesHolder, NotesHolderStorage},
|
||||
thread::Thread,
|
||||
ui::note::NoteOptions,
|
||||
unknowns::UnknownIds,
|
||||
};
|
||||
|
||||
use nostrdb::{Ndb, NoteKey, Transaction};
|
||||
use notedeck::{ImageCache, MuteFun, NoteCache, UnknownIds};
|
||||
use tracing::error;
|
||||
|
||||
use super::timeline::TimelineTabView;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
use crate::actionbar::NoteAction;
|
||||
use crate::timeline::TimelineTab;
|
||||
use crate::{
|
||||
column::Columns, imgcache::ImageCache, notecache::NoteCache, timeline::TimelineId, ui,
|
||||
ui::note::NoteOptions,
|
||||
};
|
||||
use crate::{column::Columns, timeline::TimelineId, ui, ui::note::NoteOptions};
|
||||
use egui::containers::scroll_area::ScrollBarVisibility;
|
||||
use egui::{Direction, Layout};
|
||||
use egui_tabs::TabColor;
|
||||
use nostrdb::{Ndb, Transaction};
|
||||
use notedeck::{ImageCache, NoteCache};
|
||||
use tracing::{error, warn};
|
||||
|
||||
pub struct TimelineView<'a> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::fonts::NamedFontFamily;
|
||||
use egui::{Color32, RichText, Widget};
|
||||
use nostrdb::ProfileRecord;
|
||||
use notedeck::fonts::NamedFontFamily;
|
||||
|
||||
pub struct Username<'a> {
|
||||
profile: Option<&'a ProfileRecord<'a>>,
|
||||
|
||||
Reference in New Issue
Block a user