├── .github
└── FUNDING.yml
├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── README.md
├── assets
└── missing.png
├── i18n.toml
├── i18n
├── en
│ └── cosmic_ext_toot.ftl
├── nl
│ └── cosmic_ext_toot.ftl
└── sv
│ └── cosmic_ext_toot.ftl
├── justfile
├── res
├── app.desktop
└── icons
│ └── hicolor
│ └── scalable
│ └── apps
│ └── icon.svg
├── src
├── app.rs
├── config.rs
├── error.rs
├── i18n.rs
├── main.rs
├── pages.rs
├── pages
│ ├── home.rs
│ ├── notifications.rs
│ └── public.rs
├── settings.rs
├── subscriptions.rs
├── subscriptions
│ ├── home.rs
│ ├── notifications.rs
│ └── public.rs
├── utils.rs
└── widgets
│ ├── account.rs
│ ├── mod.rs
│ ├── notification.rs
│ └── status.rs
└── testr
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: edfloreshz
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: edfloreshz
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: edfloreshz
14 | thanks_dev: # Replace with a single thanks.dev username
15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .cargo/
2 | *.pdb
3 | **/*.rs.bk
4 | debug/
5 | target/
6 | vendor/
7 | vendor.tar
8 | debian/*
9 | !debian/changelog
10 | !debian/control
11 | !debian/copyright
12 | !debian/install
13 | !debian/rules
14 | !debian/source
15 | .vscode
16 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cosmic-ext-toot"
3 | version = "0.1.0"
4 | edition = "2021"
5 | repository = "https://github.com/edfloreshz/toot"
6 |
7 | [dependencies]
8 | capitalize = "0.3.4"
9 | futures-util = "0.3.31"
10 | html2text = "0.13.4"
11 | i18n-embed-fl = "0.9.2"
12 | keytar = "0.1.6"
13 | open = "5.3.0"
14 | reqwest = "0.12.9"
15 | rust-embed = "8.5.0"
16 | thiserror = "2.0.3"
17 | time = "0.3.36"
18 | tracing = "0.1.40"
19 |
20 | [dependencies.mastodon-async]
21 | git = "https://github.com/edfloreshz-ext/mastodon-async"
22 | features = ["all"]
23 |
24 | [dependencies.serde]
25 | version = "1.0.215"
26 | features = ["derive"]
27 |
28 | [dependencies.chrono]
29 | version = "0.4.38"
30 | features = ["serde"]
31 |
32 | [dependencies.tracing-subscriber]
33 | version = "0.3.18"
34 | features = ["env-filter"]
35 |
36 | [dependencies.i18n-embed]
37 | version = "0.15"
38 | features = ["fluent-system", "desktop-requester"]
39 |
40 | [dependencies.libcosmic]
41 | git = "https://github.com/pop-os/libcosmic.git"
42 | # See https://github.com/pop-os/libcosmic/blob/master/Cargo.toml for available features.
43 | features = [
44 | # Accessibility support
45 | "a11y",
46 | # Uses cosmic-settings-daemon to watch for config file changes
47 | "dbus-config",
48 | # Support creating additional application windows.
49 | "multi-window",
50 | # On app startup, focuses an existing instance if the app is already open
51 | "single-instance",
52 | # Uses tokio as the executor for the runtime
53 | "tokio",
54 | # Windowing support for X11, Windows, Mac, & Redox
55 | "winit",
56 | # Add Wayland support to winit
57 | "wayland",
58 | # About context drawer support
59 | "about",
60 | ]
61 |
62 | # Uncomment to test a locally-cloned libcosmic
63 | # [patch.'https://github.com/pop-os/libcosmic']
64 | # libcosmic = { path = "../libcosmic" }
65 | # cosmic-config = { path = "../libcosmic/cosmic-config" }
66 | # cosmic-theme = { path = "../libcosmic/cosmic-theme" }
67 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Toot
2 | Toot is a Mastodon client for COSMIC.
3 |
4 | ## Dependencies
5 | - libsecret-1-dev
6 |
--------------------------------------------------------------------------------
/assets/missing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cosmic-utils/toot/01235ad71025a3549cd008b0fe5d0d6e425e3d07/assets/missing.png
--------------------------------------------------------------------------------
/i18n.toml:
--------------------------------------------------------------------------------
1 | fallback_language = "en"
2 |
3 | [fluent]
4 | assets_dir = "i18n"
--------------------------------------------------------------------------------
/i18n/en/cosmic_ext_toot.ftl:
--------------------------------------------------------------------------------
1 | app-title = Toot
2 | about = About
3 | view = View
4 |
5 | ## Navbar
6 | home = Home
7 | notifications = Notifications
8 | search = Search
9 | favorites = Favorites
10 | bookmarks = Bookmarks
11 | hashtags = Hashtags
12 | lists = Lists
13 | explore = Explore
14 | local = Local
15 | federated = Federated
16 |
17 | ## About
18 | repository = Repository
19 | support = Support
20 |
21 | ## Login
22 | server-question = What's your server?
23 | server-description = If you don't have an account yet, register to a server of your choice.
24 | server-url = Server URL
25 | continue = Continue
26 |
27 | ## Authorization
28 | confirm-authorization = Confirm authorization
29 | confirm-authorization-description = Copy the authorization code from the browser and paste it here.
30 | authorization-code = Authorization code
31 |
32 | ## Context
33 | about = About
34 | profile = Profile
35 | status = Status
36 |
37 | ## Dialogs
38 | switch-instance = Switch instance
39 | logout-question = Are you sure you want to logout?
40 | logout-description = You will need to login again to access your account.
41 |
42 | ## Actions
43 | reply = Reply
44 | cancel = Cancel
45 | login = Login
46 | confirm = Confirm
47 |
--------------------------------------------------------------------------------
/i18n/nl/cosmic_ext_toot.ftl:
--------------------------------------------------------------------------------
1 | app-title = Toot
2 | about = Over
3 | view = Beeld
4 |
5 | ## Navbar
6 | home = Startpagina
7 | notifications = Meldingen
8 | search = Zoeken
9 | favorites = Favorieten
10 | bookmarks = Bladwijzers
11 | hashtags = Hashtags
12 | lists = Lijsten
13 | explore = Ontdekken
14 | local = Lokaal
15 | federated = Gefedereerd
16 |
17 | ## About
18 | repository = Repository
19 | support = Ondersteuning
20 |
21 | ## Login
22 | server-question = Wat is uw server?
23 | server-description = Als u nog geen account heeft, registreert u zich dan op een server naar keuze.
24 | server-url = Server-URL
25 | continue = Ga verder
26 |
27 | ## Authorization
28 | confirm-authorization = Autorisatie bevestigen
29 | confirm-authorization-description = Kopieer de autorisatiecode uit uw browser en plak die hier.
30 | authorization-code = Autorisatiecode
31 |
32 | ## Context
33 | about = Over
34 | profile = Profiel
35 | status = Status
36 |
37 | ## Dialogs
38 | switch-instance = Naar andere instantie overschakelen
39 | logout-question = Weet u zeker dat u wilt uitloggen?
40 | logout-description = U moet dan opnieuw inloggen om toegang te krijgen tot uw account.
41 |
42 | ## Actions
43 | reply = Reageren
44 | cancel = Annuleren
45 | login = Inloggen
46 | confirm = Bevestigen
47 |
--------------------------------------------------------------------------------
/i18n/sv/cosmic_ext_toot.ftl:
--------------------------------------------------------------------------------
1 | app-title = Toot
2 | about = Om
3 | view = Visa
4 |
5 | ## Navigeringsfältet
6 | home = Hem
7 | notifications = Aviseringar
8 | search = Sök
9 | favorites = Favoriter
10 | bookmarks = Bokmärken
11 | hashtags = Hashtaggar
12 | lists = Listor
13 | explore = Utforska
14 | local = Lokal
15 | federated = Federerat
16 |
17 | ## Om
18 | repository = Förråd
19 | support = Support
20 |
21 | ## Inloggning
22 | server-question = Vad är din server?
23 | server-description = Om du inte har ett konto ännu, registrera dig på en valfri server.
24 | server-url = Server webbadress
25 | continue = Fortsätt
26 |
27 | ## Auktorisation
28 | confirm-authorization = Bekräfta auktorisation
29 | confirm-authorization-description = Kopiera auktoriseringskoden från webbläsaren och klistra in den här.
30 | authorization-code = Auktoriseringskod
31 |
32 | ## Kontext
33 | about = Om
34 | profile = Profil
35 | status = Status
36 |
37 | ## Åtgärder
38 | reply = Svara
39 | cancel = Avbryt
40 | login = Logga in
41 | confirm = Bekräfta
42 |
--------------------------------------------------------------------------------
/justfile:
--------------------------------------------------------------------------------
1 | name := 'cosmic-ext-toot'
2 | appid := 'dev.edfloreshz.Toot'
3 |
4 | rootdir := ''
5 | prefix := '/usr'
6 |
7 | base-dir := absolute_path(clean(rootdir / prefix))
8 |
9 | bin-src := 'target' / 'release' / name
10 | bin-dst := base-dir / 'bin' / name
11 |
12 | desktop := appid + '.desktop'
13 | desktop-src := 'res' / desktop
14 | desktop-dst := clean(rootdir / prefix) / 'share' / 'applications' / desktop
15 |
16 | icons-src := 'res' / 'icons' / 'hicolor'
17 | icons-dst := clean(rootdir / prefix) / 'share' / 'icons' / 'hicolor'
18 |
19 | icon-svg-src := icons-src / 'scalable' / 'apps' / 'icon.svg'
20 | icon-svg-dst := icons-dst / 'scalable' / 'apps' / appid + '.svg'
21 |
22 | # Default recipe which runs `just build-release`
23 | default: build-release
24 |
25 | # Runs `cargo clean`
26 | clean:
27 | cargo clean
28 |
29 | # Removes vendored dependencies
30 | clean-vendor:
31 | rm -rf .cargo vendor vendor.tar
32 |
33 | # `cargo clean` and removes vendored dependencies
34 | clean-dist: clean clean-vendor
35 |
36 | # Compiles with debug profile
37 | build-debug *args:
38 | cargo build {{args}}
39 |
40 | # Compiles with release profile
41 | build-release *args: (build-debug '--release' args)
42 |
43 | # Compiles release profile with vendored dependencies
44 | build-vendored *args: vendor-extract (build-release '--frozen --offline' args)
45 |
46 | # Runs a clippy check
47 | check *args:
48 | cargo clippy --all-features {{args}} -- -W clippy::pedantic
49 |
50 | # Runs a clippy check with JSON message format
51 | check-json: (check '--message-format=json')
52 |
53 | # Run the application for testing purposes
54 | run *args:
55 | env RUST_BACKTRACE=full cargo run --release {{args}}
56 |
57 | # Installs files
58 | install:
59 | install -Dm0755 {{bin-src}} {{bin-dst}}
60 | install -Dm0644 res/app.desktop {{desktop-dst}}
61 | install -Dm0644 {{icon-svg-src}} {{icon-svg-dst}}
62 |
63 | # Uninstalls installed files
64 | uninstall:
65 | rm {{bin-dst}} {{desktop-dst}} {{icon-svg-dst}}
66 |
67 | # Vendor dependencies locally
68 | vendor:
69 | #!/usr/bin/env bash
70 | mkdir -p .cargo
71 | cargo vendor --sync Cargo.toml | head -n -1 > .cargo/config.toml
72 | echo 'directory = "vendor"' >> .cargo/config.toml
73 | echo >> .cargo/config.toml
74 | echo '[env]' >> .cargo/config.toml
75 | if [ -n "${SOURCE_DATE_EPOCH}" ]
76 | then
77 | source_date="$(date -d "@${SOURCE_DATE_EPOCH}" "+%Y-%m-%d")"
78 | echo "VERGEN_GIT_COMMIT_DATE = \"${source_date}\"" >> .cargo/config.toml
79 | fi
80 | if [ -n "${SOURCE_GIT_HASH}" ]
81 | then
82 | echo "VERGEN_GIT_SHA = \"${SOURCE_GIT_HASH}\"" >> .cargo/config.toml
83 | fi
84 | tar pcf vendor.tar .cargo vendor
85 | rm -rf .cargo vendor
86 |
87 | # Extracts vendored dependencies
88 | vendor-extract:
89 | rm -rf vendor
90 | tar pxf vendor.tar
91 |
--------------------------------------------------------------------------------
/res/app.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Name=Toot
3 | Exec=cosmic-ext-toot %u
4 | Terminal=false
5 | Type=Application
6 | StartupNotify=true
7 | Icon=dev.edfloreshz.Toot
8 | Categories=COSMIC;
9 | Keywords=toot;mastodon;fediverse;
10 | MimeType=x-scheme-handler/toot;
11 |
--------------------------------------------------------------------------------
/res/icons/hicolor/scalable/apps/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/app.rs:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: {{LICENSE}}
2 |
3 | use crate::config::TootConfig;
4 | use crate::pages::public::TimelineType;
5 | use crate::pages::Page;
6 | use crate::utils::{self, Cache};
7 | use crate::widgets::status::StatusOptions;
8 | use crate::{fl, pages, widgets};
9 | use cosmic::app::{context_drawer, Core, Task};
10 | use cosmic::cosmic_config;
11 | use cosmic::iced::alignment::{Horizontal, Vertical};
12 | use cosmic::iced::{Length, Subscription};
13 | use cosmic::widget::about::About;
14 | use cosmic::widget::image::Handle;
15 | use cosmic::widget::menu::{ItemHeight, ItemWidth};
16 | use cosmic::widget::{self, menu, nav_bar};
17 | use cosmic::{Application, ApplicationExt, Apply, Element};
18 | use mastodon_async::helpers::toml;
19 | use mastodon_async::prelude::{Account, Notification, Scopes, Status, StatusId};
20 | use mastodon_async::registration::Registered;
21 | use mastodon_async::{Data, Mastodon, NewStatus, Registration};
22 | use reqwest::Url;
23 | use std::collections::{HashMap, VecDeque};
24 | use std::str::FromStr;
25 |
26 | const REPOSITORY: &str = "https://github.com/edfloreshz/toot";
27 | const SUPPORT: &str = "https://github.com/edfloreshz/toot/issues";
28 |
29 | pub struct AppModel {
30 | core: Core,
31 | about: About,
32 | nav: nav_bar::Model,
33 | context_page: ContextPage,
34 | key_binds: HashMap,
35 | dialog_pages: VecDeque