UTDTZCTXAAP6AHENYQP7MOQ5QNIKKXN34NV2ONWEGM4HA4FU637AC 6YZAVBWU6E5FYOI5JGEIPXGZLIKAW6LS2AOFIQWEE5DMOPPCD5PQC SWWE2R6MVBX5CNM6X3WLXZTSRTU53PBJL7WJSFVF77XBPXDX4COAC UB2ITZJSDADVINSQEZ3HA6PVGA7OA6JYFG5GMSO7Y7LOXJC4FI7AC KT5UYXGKEEXUHURNOYFVIG7WQ3Y3SJZMM2TP4OSW6NXSXQ5XXRHAC YBJRDOTCX3ZRDB5EVXJBR55FX3CADCSIGMYWNYVC2PD5W3GXR3DQC D7A7MSIHJS3IAOLEPK52M4CZLDPLO7JB3Y62XACT2AM6UUCPQ6BAC PTFDJ567XGGF26TE7KVQT7WPZIWV737DBO24VFIPEWPVAVKEKADQC GWZGYNIBQP2AA7WYULNBS2BCV4B36IHK4OS7XHVOTUUG27E76XFQC 3SYSJKYLVCXR54LRUPL6GOQISSJS6XWK4M6PRQRCKZN7F23NNVEAC 23SFYK4Q5NKBPJG53PQNPWQH6UOUU2YKJEL7RLXYBRLJOJYV7AWQC OPXFZKEBDHZZLXEJ2JRDYBOJH6YIN7UZNZYHVHMWMQVDTE2ZD53QC ACDXXAX26ZJJFKJDGRC2GOSJY5JHQWCSTP55SYI6D6LH5UIRYUBAC SGHF5QCV4AYIYLXURHVUODXFAN5UWP6GBNGYZUUMPWWLKYH45RTAC DXAYDIMQ7BYEI3ASOHKADQWSMVJOA2ZVNEL2TDENJCJKX2U4GMWAC SASAN2XCWDQ2VEHZ7TAQEN2R3Y7AG7JUGEFVRL4DZAGHXDFEZFRQC 3TLPJ57B2OD5OWJN5WMS7A4W7IGFUWJJHVIXRM34VT6KUN6R4YSAC PTWZYQFRWWUOE2WMQT26CKZKFSHAIJVJS3QWHJFYUFDRRTVPHSUAC A6Z4O6RC33HYWP7JIVQ6FDWE4EOCQWQTIGENK2WAHUGSHDDLSA7QC 7BLZN73OYUAJEYTJ6WWHRZ7S7ONDGRBKNJGFGW62NAIZBUK3CECQC 5ZRDYL6KIQPUI3ZZETH5KJ64N6RUF7KYM3P6Q6HER5XVJZ7GZ4WQC 3XRG4BB6V5V4DICZCMOZMLQNTANWKPO7BBRATTXOZLRNSEUQIA5AC WAOGSCOJ5A372BZKHEYD2BCDBCENNVLFYW3INKUOOAZMDADDIFIQC WH57EHNML4OTGQQZBT2SG6SOFTBOD6OJPJYHJVGPH22CSSOE25AAC EJPSD5XO43DWUBBZGNQMY4TMCAXL5EWCGX3OEHUERQ5GRASGWQLQC YK3MOJJLRYEKZ4FUCNJ3YKMTKOINWIYOJKR3ER7IRSGTC7O6FJZQC 7WCB5YQJJZIPUAFHTCQBWNI6ZM5XMIQJAKTLYTR7NOR5NKESRMDQC AZ5D2LQUSYVWVEP7ISFDSZTMZ65UEHZATILMDQ4TYLCKJH4Q3TIAC PKLUHYE4BGIMJKU6VKGBGSHEB2ZT53OYMTFBYCZYCO4J3RVTRXSAC CULHFNIVQ3ATML2W3Z45RARZ2LHGXONYTGGN2ETWAAMV7R3Y67AQC U3EAZKHRN3DBOOYM4GDEVJK2DJ6ULHOPOHJLCCHYV2EEPUBMYX5QC KF2LDB5YIXMXBZK6KJWJOLJL66TN2KDXPH3NKEGGCQ5EVOZB77BQC IFQPVMBD552DZ3B5HCM6W6MI2SB6576ZYJNU5KVA3O4YPZAUEFHAC LFEMJYYDO45ASMQSOJ3TNID7B5UZXDHB3NWFZJXWOAWNBS6GMDEAC 5O4FWCFP4ZPAS7WKSYPHN76ML3O2S4JUOYWOV2ETD4TF2H6KZ6AQC FU6P5QLG4GVLHVB4O5TCEPJF4X4FGDUBONQFRYP4U5KEPIYLUWJQC YGZ3VCW4OAJYPI2CYK3MTABNFY7Y2ENSSTFE5ZZ4K6HK57FCU3XQC ODCT4QJNJLQTDNFPIF7HX4XCFTEXZBESG3PTD276O7TWB7MSGWMQC KLR5FRIBS6UOH3S3XAOE22TJACVSVOY7TOLW22DIWNGY27S6WZRAC MYGIBRRHHXPKVRAMQQRJTZH74L2XOK3SF7J57JPCRKSVRLZ2D6NQC MsgIn::Push => {let result = push(&internal_state.path).await;let _ = msg_out_tx.send(MsgOut::Pushed { result });
MsgIn::Push { channel } => {let result = push(&internal_state.path, &channel).await;let _ = msg_out_tx.send(MsgOut::Pushed { channel, result });
MsgIn::Pull => {let result = pull(&internal_state.path).await;let _ = msg_out_tx.send(MsgOut::Pulled { result });
MsgIn::Pull { channel } => {let result = pull(&internal_state.path, &channel).await;let _ = msg_out_tx.send(MsgOut::Pulled { channel, result });
let row = row(buttons);el(row.spacing(2).wrap())
el(row(buttons).spacing(2).wrap())}fn view_jobs<'a>(jobs: &IndexSet<Job>,current_channel: &str,) -> Element<'a, Msg, Theme> {let jobs: Vec<_> = itertools::intersperse_with(jobs.iter().map(|job| view_job(job, current_channel)),|| el(text(", ")),).collect();el(row(jobs).spacing(2).wrap())}fn view_job<'a>(job: &Job, current_channel: &str) -> Element<'a, Msg, Theme> {match job {Job::Pull { channel } => {if channel == current_channel {el(text("Pulling"))} else {el(text(format!("Pulling {channel}")))}}Job::Push { channel } => {if channel == current_channel {el(text("Pushing"))} else {el(text(format!("Pushing {channel}")))}}}
// TODO switch state while pushing to display progressstate.repo_tx_in.send(repo::MsgIn::Push).unwrap();
if let Some(ReadyState { repo, jobs, .. }) =model::is_ready_mut(&mut state.model){jobs.insert(model::Job::Push {channel: repo.channel.clone(),});state.repo_tx_in.send(repo::MsgIn::Push {channel: repo.channel.clone(),}).unwrap();}
// TODO switch state while pulling to display progressstate.repo_tx_in.send(repo::MsgIn::Pull).unwrap();
if let Some(ReadyState { repo, jobs, .. }) =model::is_ready_mut(&mut state.model){jobs.insert(model::Job::Pull {channel: repo.channel.clone(),});state.repo_tx_in.send(repo::MsgIn::Pull {channel: repo.channel.clone(),}).unwrap();}
repo::MsgOut::Pushed { result } => match result {Ok(()) => Task::none(),Err(err) => report_err(state, err.to_string()),
repo::MsgOut::Pushed { channel, result } => {let task = match result {Ok(()) => report_info(state, format!("Pushed to {channel}")),Err(repo::PushError::Empty) => report_info(state, format!("Nothing to push to {channel}")),Err(err) => report_err(state, err.to_string()),};if let Some(ReadyState { jobs, .. }) =model::is_ready_mut(&mut state.model){jobs.swap_remove(&Job::Push{ channel });}task
repo::MsgOut::Pulled { result } => match result {Ok(()) => Task::none(),Err(err) => report_err(state, err.to_string()),
repo::MsgOut::Pulled { channel, result } =>{let task = match result {Ok(()) => report_info(state, format!("Pulled from {channel}")),Err(repo::PullError::Empty) => report_info(state, format!("Nothing to pull from {channel}")),Err(err) => report_err(state, err.to_string()),};if let Some(ReadyState { jobs, .. }) =model::is_ready_mut(&mut state.model){jobs.swap_remove(&Job::Pull{ channel });}task