Skip to content

Commit a29866d

Browse files
committed
Refactor client facade and action routing
1 parent ea046a4 commit a29866d

31 files changed

Lines changed: 1704 additions & 960 deletions

src/app/action.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ pub enum LoadMoreRequest {
2424
Notifications { cursor: String },
2525
}
2626

27+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
28+
pub(crate) enum ActionDomain {
29+
App,
30+
Accounts,
31+
Channels,
32+
Messages,
33+
Notifications,
34+
Audit,
35+
Feeds,
36+
}
37+
2738
#[derive(Clone, Debug, PartialEq, Eq)]
2839
pub enum Action {
2940
CreateInvite,
@@ -193,3 +204,85 @@ pub enum Action {
193204
},
194205
LoadOlder,
195206
}
207+
208+
impl Action {
209+
pub(crate) fn domain(&self) -> ActionDomain {
210+
match self {
211+
Self::OpenAccount => ActionDomain::App,
212+
Self::CreateInvite
213+
| Self::CreateInviteWithOptions { .. }
214+
| Self::CompleteOnboarding { .. }
215+
| Self::ListUsers
216+
| Self::SetUsername { .. }
217+
| Self::SetProfile { .. }
218+
| Self::SaveAccountSettings { .. }
219+
| Self::SetUserDisabled { .. }
220+
| Self::SetUserRole { .. }
221+
| Self::ListKeys
222+
| Self::ListMyKeys
223+
| Self::AddKey { .. }
224+
| Self::CreateDeviceLinkToken { .. }
225+
| Self::LabelKey { .. }
226+
| Self::RevokeKey { .. }
227+
| Self::ListInvites
228+
| Self::RevokeInvite { .. } => ActionDomain::Accounts,
229+
Self::CreateChannel { .. }
230+
| Self::JoinChannel { .. }
231+
| Self::LeaveChannel { .. }
232+
| Self::ListChannels
233+
| Self::RenameChannel { .. }
234+
| Self::SetChannelTopic { .. }
235+
| Self::SetChannelArchived { .. }
236+
| Self::ListChannelMembers { .. }
237+
| Self::AddChannelMember { .. }
238+
| Self::RemoveChannelMember { .. } => ActionDomain::Channels,
239+
Self::CreateThread { .. }
240+
| Self::AddComment { .. }
241+
| Self::OpenDm { .. }
242+
| Self::SendDm { .. }
243+
| Self::MarkThreadRead
244+
| Self::MarkThreadUnread
245+
| Self::MarkDmRead
246+
| Self::MarkDmUnread
247+
| Self::NextUnread
248+
| Self::RenameThread { .. }
249+
| Self::DeleteThread
250+
| Self::SetThreadArchived { .. }
251+
| Self::SetThreadPinned { .. }
252+
| Self::SetThreadMuted { .. }
253+
| Self::EditComment { .. }
254+
| Self::DeleteComment { .. }
255+
| Self::EditDm { .. }
256+
| Self::DeleteDm { .. }
257+
| Self::SetDmMuted { .. }
258+
| Self::SetMessageSaved { .. }
259+
| Self::React { .. }
260+
| Self::Unreact { .. } => ActionDomain::Messages,
261+
Self::ListMentions
262+
| Self::ListNotifications
263+
| Self::OpenSourceTarget { .. }
264+
| Self::MarkNotificationRead { .. }
265+
| Self::ArchiveNotifications
266+
| Self::SetTerminalNotifications { .. }
267+
| Self::ShowTerminalNotificationsStatus => ActionDomain::Notifications,
268+
Self::ListAudit => ActionDomain::Audit,
269+
Self::Search { .. }
270+
| Self::OpenLabel { .. }
271+
| Self::ListSaved
272+
| Self::LoadMore { .. }
273+
| Self::LoadOlder => ActionDomain::Feeds,
274+
}
275+
}
276+
277+
pub(crate) fn refreshes_after(&self) -> bool {
278+
!matches!(
279+
self,
280+
Self::LoadMore { .. }
281+
| Self::Search { .. }
282+
| Self::OpenLabel { .. }
283+
| Self::OpenAccount
284+
| Self::ListSaved
285+
| Self::ListNotifications
286+
)
287+
}
288+
}

src/app/lifecycle.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ pub(crate) async fn fetch_refresh(
4242
inputs.history_limit,
4343
)
4444
.await?;
45-
let terminal_notifications_enabled = client.terminal_notifications_enabled(&account.id).await?;
45+
let terminal_notifications_enabled = client
46+
.notifications()
47+
.terminal_notifications_enabled()
48+
.await?;
4649
Ok(RefreshFetched {
4750
account,
4851
snapshot,

src/app/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod input;
44
mod render;
55
mod state;
66
mod theme;
7+
pub(crate) use action::ActionDomain;
78
pub use action::{Action, LoadMoreRequest, SourceFocus, SourceTarget};
89

910
use std::{

src/client/accounts.rs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
use crate::features::{
2+
accounts::model::{Account, AccountSummary, InviteSummary, Role, SshKeySummary},
3+
channels::model::ChannelMemberSummary,
4+
};
5+
6+
use super::ClientSession;
7+
8+
pub struct AccountsClient<'a> {
9+
session: &'a ClientSession,
10+
}
11+
12+
impl ClientSession {
13+
pub fn accounts(&self) -> AccountsClient<'_> {
14+
AccountsClient { session: self }
15+
}
16+
}
17+
18+
impl AccountsClient<'_> {
19+
fn actor_id(&self) -> &str {
20+
self.session.actor_id()
21+
}
22+
23+
pub async fn create_invite(&self) -> anyhow::Result<String> {
24+
self.session
25+
.state()
26+
.create_invite(self.actor_id().to_string())
27+
.await
28+
}
29+
30+
pub async fn create_invite_with_options(
31+
&self,
32+
role: Role,
33+
ttl_hours: Option<i64>,
34+
) -> anyhow::Result<String> {
35+
self.session
36+
.state()
37+
.create_invite_with_options(self.actor_id(), role, ttl_hours)
38+
.await
39+
}
40+
41+
pub async fn complete_onboarding(&self, username: &str) -> anyhow::Result<Account> {
42+
self.session
43+
.state()
44+
.complete_onboarding(self.actor_id(), username)
45+
.await
46+
}
47+
48+
pub async fn list_accounts(&self) -> anyhow::Result<Vec<AccountSummary>> {
49+
self.session.state().list_accounts(self.actor_id()).await
50+
}
51+
52+
pub async fn rename_self(&self, username: &str) -> anyhow::Result<()> {
53+
self.session
54+
.state()
55+
.rename_user(self.actor_id(), self.actor_id(), username)
56+
.await
57+
}
58+
59+
pub async fn set_self_display_name(&self, display_name: &str) -> anyhow::Result<()> {
60+
self.session
61+
.state()
62+
.set_display_name(self.actor_id(), self.actor_id(), display_name)
63+
.await
64+
}
65+
66+
pub async fn set_user_disabled(&self, username: &str, disabled: bool) -> anyhow::Result<()> {
67+
self.session
68+
.state()
69+
.set_user_disabled(self.actor_id(), username, disabled)
70+
.await
71+
}
72+
73+
pub async fn set_user_role(&self, username: &str, role: Role) -> anyhow::Result<()> {
74+
self.session
75+
.state()
76+
.set_user_role(self.actor_id(), username, role)
77+
.await
78+
}
79+
80+
pub async fn list_ssh_keys(&self) -> anyhow::Result<Vec<SshKeySummary>> {
81+
self.session.state().list_ssh_keys(self.actor_id()).await
82+
}
83+
84+
pub async fn list_my_ssh_keys(&self) -> anyhow::Result<Vec<SshKeySummary>> {
85+
self.session.state().list_my_ssh_keys(self.actor_id()).await
86+
}
87+
88+
pub async fn create_device_link_token(&self, label: Option<&str>) -> anyhow::Result<String> {
89+
self.session
90+
.state()
91+
.create_device_link_token(self.actor_id(), label)
92+
.await
93+
}
94+
95+
pub async fn add_ssh_key(
96+
&self,
97+
username: Option<&str>,
98+
public_key: &str,
99+
label: Option<&str>,
100+
) -> anyhow::Result<SshKeySummary> {
101+
self.session
102+
.state()
103+
.add_ssh_key(self.actor_id(), username, public_key, label)
104+
.await
105+
}
106+
107+
pub async fn label_ssh_key(&self, key: &str, label: &str) -> anyhow::Result<()> {
108+
self.session
109+
.state()
110+
.label_ssh_key(self.actor_id(), key, label)
111+
.await
112+
}
113+
114+
pub async fn revoke_ssh_key(&self, key: &str) -> anyhow::Result<()> {
115+
self.session
116+
.state()
117+
.revoke_ssh_key(self.actor_id(), key)
118+
.await
119+
}
120+
121+
pub async fn list_invites(&self) -> anyhow::Result<Vec<InviteSummary>> {
122+
self.session.state().list_invites(self.actor_id()).await
123+
}
124+
125+
pub async fn revoke_invite(&self, invite_id: &str) -> anyhow::Result<()> {
126+
self.session
127+
.state()
128+
.revoke_invite(self.actor_id(), invite_id)
129+
.await
130+
}
131+
132+
pub async fn list_channel_members(
133+
&self,
134+
slug: &str,
135+
) -> anyhow::Result<Vec<ChannelMemberSummary>> {
136+
self.session
137+
.state()
138+
.list_channel_members(self.actor_id(), slug)
139+
.await
140+
}
141+
}

src/client/audit.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use crate::features::audit::model::AuditEntry;
2+
3+
use super::ClientSession;
4+
5+
pub struct AuditClient<'a> {
6+
session: &'a ClientSession,
7+
}
8+
9+
impl ClientSession {
10+
pub fn audit(&self) -> AuditClient<'_> {
11+
AuditClient { session: self }
12+
}
13+
}
14+
15+
impl AuditClient<'_> {
16+
pub async fn list_audit(&self, limit: i64) -> anyhow::Result<Vec<AuditEntry>> {
17+
self.session
18+
.state()
19+
.list_audit(self.session.actor_id(), limit)
20+
.await
21+
}
22+
}

src/client/channels.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use crate::features::channels::model::{ChannelDirectoryItem, ChannelMemberSummary};
2+
3+
use super::ClientSession;
4+
5+
pub struct ChannelsClient<'a> {
6+
session: &'a ClientSession,
7+
}
8+
9+
impl ClientSession {
10+
pub fn channels(&self) -> ChannelsClient<'_> {
11+
ChannelsClient { session: self }
12+
}
13+
}
14+
15+
impl ChannelsClient<'_> {
16+
fn actor_id(&self) -> &str {
17+
self.session.actor_id()
18+
}
19+
20+
pub async fn create_channel(&self, name: String, private: bool) -> anyhow::Result<String> {
21+
self.session
22+
.state()
23+
.create_channel(self.actor_id().to_string(), name, private)
24+
.await
25+
}
26+
27+
pub async fn join_channel(&self, slug: String) -> anyhow::Result<String> {
28+
self.session
29+
.state()
30+
.join_channel(self.actor_id().to_string(), slug)
31+
.await
32+
}
33+
34+
pub async fn leave_channel(&self, slug: &str) -> anyhow::Result<()> {
35+
self.session
36+
.state()
37+
.leave_channel(self.actor_id(), slug)
38+
.await
39+
}
40+
41+
pub async fn list_channels(
42+
&self,
43+
include_archived: bool,
44+
) -> anyhow::Result<Vec<ChannelDirectoryItem>> {
45+
self.session
46+
.state()
47+
.list_channels(self.actor_id(), include_archived)
48+
.await
49+
}
50+
51+
pub async fn rename_channel(&self, slug: &str, name: &str) -> anyhow::Result<()> {
52+
self.session
53+
.state()
54+
.rename_channel(self.actor_id(), slug, name)
55+
.await
56+
}
57+
58+
pub async fn set_channel_topic(&self, slug: &str, topic: &str) -> anyhow::Result<()> {
59+
self.session
60+
.state()
61+
.set_channel_topic(self.actor_id(), slug, topic)
62+
.await
63+
}
64+
65+
pub async fn set_channel_archived(&self, slug: &str, archived: bool) -> anyhow::Result<()> {
66+
self.session
67+
.state()
68+
.set_channel_archived(self.actor_id(), slug, archived)
69+
.await
70+
}
71+
72+
pub async fn list_channel_members(
73+
&self,
74+
slug: &str,
75+
) -> anyhow::Result<Vec<ChannelMemberSummary>> {
76+
self.session
77+
.state()
78+
.list_channel_members(self.actor_id(), slug)
79+
.await
80+
}
81+
82+
pub async fn add_channel_member(&self, slug: &str, username: &str) -> anyhow::Result<()> {
83+
self.session
84+
.state()
85+
.add_channel_member(self.actor_id(), slug, username)
86+
.await
87+
}
88+
89+
pub async fn remove_channel_member(&self, slug: &str, username: &str) -> anyhow::Result<()> {
90+
self.session
91+
.state()
92+
.remove_channel_member(self.actor_id(), slug, username)
93+
.await
94+
}
95+
}

0 commit comments

Comments
 (0)