use super::*;
use crate::route::{code, discussions, issues, pulls};
#[must_use]
pub fn star(state: &mut State) -> Vec<Cmd> {
let Some(repo) = state.route().and_then(Route::repo).cloned() else {
return state.just_say("Open a repository to star it");
};
let Some(overview) = state.overview(&repo) else {
return state.just_say("The repository hasn't loaded yet");
};
let (id, starred) = (overview.id.clone(), !overview.starred);
set_starred(state, &repo, starred);
let star = Change::Star { repo, id, starred };
vec![crate::act::send(star, crate::act::By::Star)]
}
pub fn set_starred(state: &mut State, repo: &RepoId, starred: bool) {
if let Some(remote) = state.data.get_mut(&DataKey::Repo(repo.clone()))
&& let Some(Data::Repo(o)) = &mut remote.data
&& o.starred != starred
{
o.starred = starred;
o.summary.stars = if starred {
o.summary.stars + 1
} else {
o.summary.stars.saturating_sub(1)
};
remote.changed();
}
}
#[must_use]
pub(super) fn quote_reply(state: &mut State) -> Vec<Cmd> {
let Screen::Page(p) = state.screen() else {
return Vec::new();
};
match p.selected_link().cloned() {
Some(Link::Quote { author, body, at }) => {
let quoted: String = body.trim().lines().map(|l| format!("> {l}\n")).collect();
comment_with(state, &format!("> @{author} wrote:\n{quoted}\n"), Some(at))
}
_ => {
let down = state.first_key(Action::Down);
state.just_say(format!(
"Select a comment to quote: {down} goes comment by comment"
))
}
}
}
#[must_use]
pub(super) fn comment_with(state: &mut State, text: &str, quoting: Option<String>) -> Vec<Cmd> {
let target = match state.route() {
Some(Route::Issues(issues::Issue { repo, number })) => {
let key = DataKey::Issue(repo.clone(), *number);
match state.get(&key) {
Some(Data::Issue(Some(issue))) => {
Some((issue.id.clone(), format!("{repo}#{number}")))
}
_ => None,
}
}
Some(Route::Pulls(pulls::Pr { pr, .. })) => {
state.activity(pr).map(|a| (a.id.clone(), pr.to_string()))
}
Some(Route::Discussions(discussions::Discussion { .. })) => {
return crate::discuss::act(state, Action::Comment);
}
Some(Route::Code(code::Commit { repo, oid, .. })) => {
let target = compose::Target::Commit {
repo: repo.clone(),
oid: oid.clone(),
};
return state.compose(target, text);
}
_ => {
return state.just_say("Comments go on issues and pull requests");
}
};
let Some((subject_id, name)) = target else {
return state.just_say("Still loading");
};
let target = compose::Target::Conversation {
subject_id,
name,
quoting,
};
state.compose(target, text)
}