added more boilerplate for using login, but the misskey login thing doesnt work so bleh
This commit is contained in:
parent
e2776996ef
commit
eef6c40dc1
|
@ -57,6 +57,17 @@ dependencies = [
|
|||
"event-listener",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-tungstenite"
|
||||
version = "0.18.0"
|
||||
|
@ -609,6 +620,7 @@ name = "kkdisp"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"serde",
|
||||
"termion",
|
||||
]
|
||||
|
@ -618,6 +630,7 @@ name = "kkx"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"futures",
|
||||
"kkdisp",
|
||||
"misskey",
|
||||
|
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.68"
|
||||
async-trait = "0.1.63"
|
||||
# termion = "2.0.1"
|
||||
|
||||
[dependencies.serde]
|
||||
|
@ -14,4 +15,4 @@ version = "1"
|
|||
features = ["std", "derive"]
|
||||
|
||||
[dependencies.termion]
|
||||
git = "https://sectorinf.com/emilis/termion"
|
||||
git = "https://sectorinf.com/emilis/termion"
|
||||
|
|
|
@ -227,7 +227,7 @@ where
|
|||
);
|
||||
let mut events_iter = termion::async_stdin().events();
|
||||
let mut plans =
|
||||
PlanState::from_plans(view.init()?, base_colorset)?;
|
||||
PlanState::from_plans(view.init().await?, base_colorset)?;
|
||||
plans.render(&mut screen)?;
|
||||
// FIXME: current loop means that pasting a string with len >1
|
||||
// results in only the first character being rendered, until
|
||||
|
@ -235,7 +235,7 @@ where
|
|||
loop {
|
||||
if let Some(msg) = view.query() {
|
||||
plans = plans.act_on(
|
||||
view.update(Event::Message(msg))?,
|
||||
view.update(Event::Message(msg)).await?,
|
||||
&mut screen,
|
||||
)?;
|
||||
continue;
|
||||
|
@ -304,7 +304,8 @@ where
|
|||
// }
|
||||
|
||||
if let Some(event) = event {
|
||||
plans = plans.act_on(view.update(event)?, &mut screen)?;
|
||||
plans = plans
|
||||
.act_on(view.update(event).await?, &mut screen)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -368,10 +369,11 @@ pub enum Action {
|
|||
Nothing,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait View {
|
||||
type Message;
|
||||
|
||||
fn init(
|
||||
async fn init(
|
||||
&mut self,
|
||||
) -> std::result::Result<PlanLayers, anyhow::Error>;
|
||||
|
||||
|
@ -380,7 +382,7 @@ pub trait View {
|
|||
// from some sort of queue, or None if there's an empty queue.
|
||||
fn query(&mut self) -> Option<Self::Message>;
|
||||
|
||||
fn update(
|
||||
async fn update(
|
||||
&mut self,
|
||||
event: Event<Self::Message>,
|
||||
) -> std::result::Result<Action, anyhow::Error>;
|
||||
|
|
|
@ -9,6 +9,7 @@ edition = "2021"
|
|||
anyhow = "1.0.68"
|
||||
kkdisp = { version = "0.1.0", path = "../kkdisp" }
|
||||
futures = "0.3.25"
|
||||
async-trait = "0.1.63"
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1.24.2"
|
||||
|
|
|
@ -6,10 +6,12 @@ use kkdisp::{
|
|||
view::{Event, Key},
|
||||
Action,
|
||||
};
|
||||
use misskey::{StreamingClientExt, WebSocketClient};
|
||||
use tokio::sync::mpsc::{self, Receiver, Sender};
|
||||
use misskey::{
|
||||
websocket::WebSocketClientBuilder, ClientExt, StreamingClientExt,
|
||||
WebSocketClient,
|
||||
};
|
||||
|
||||
use crate::Message;
|
||||
use crate::{AuthDetail, Message};
|
||||
pub enum LoginFocus {
|
||||
Hostname,
|
||||
Token,
|
||||
|
@ -30,7 +32,7 @@ pub struct LoginPrompt {
|
|||
token: String,
|
||||
error: Option<String>,
|
||||
focus: LoginFocus,
|
||||
client: Option<WebSocketClient>,
|
||||
client: Option<AuthDetail>,
|
||||
}
|
||||
|
||||
impl LoginPrompt {
|
||||
|
@ -62,12 +64,13 @@ impl LoginPrompt {
|
|||
LoginFocus::OK => {}
|
||||
}
|
||||
}
|
||||
pub fn query(&mut self) -> Option<()> {
|
||||
todo!()
|
||||
pub fn query(&mut self) -> Option<AuthDetail> {
|
||||
self.client.take()
|
||||
}
|
||||
|
||||
pub fn attempt(&mut self) {
|
||||
let hostname = self.hostname.clone();
|
||||
pub async fn attempt(&mut self) {
|
||||
let hostname =
|
||||
self.hostname.trim_end_matches('/').to_string();
|
||||
if hostname.len() == 0 {
|
||||
self.error = Some("empty hostname".into());
|
||||
self.focus = LoginFocus::Hostname;
|
||||
|
@ -79,17 +82,42 @@ impl LoginPrompt {
|
|||
self.focus = LoginFocus::Token;
|
||||
return;
|
||||
}
|
||||
todo!();
|
||||
let auth = AuthDetail { hostname, token };
|
||||
|
||||
match auth.normal().await {
|
||||
Ok(client) => {
|
||||
match client.recommended_users().try_next().await {
|
||||
Ok(next) => {
|
||||
eprintln!("next: {:#?}", next);
|
||||
self.client = Some(auth);
|
||||
}
|
||||
Err(err) => {
|
||||
self.error = Some(err.to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(err) => {
|
||||
self.error = Some(err.to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
fn down(&mut self) {
|
||||
self.focus = match self.focus {
|
||||
LoginFocus::Hostname => LoginFocus::Token,
|
||||
LoginFocus::Token => LoginFocus::OK,
|
||||
LoginFocus::OK => LoginFocus::Hostname,
|
||||
};
|
||||
}
|
||||
|
||||
pub async fn update(
|
||||
&mut self,
|
||||
event: Event<Message>,
|
||||
) -> Result<Action, anyhow::Error> {
|
||||
match event {
|
||||
Event::Link(lnk) => {
|
||||
if lnk == "ok" {
|
||||
self.attempt();
|
||||
self.attempt().await;
|
||||
Ok(Action::ReplaceAll(vec![self.plan()]))
|
||||
} else if lnk == "token" {
|
||||
self.focus = LoginFocus::Token;
|
||||
|
@ -110,9 +138,10 @@ impl LoginPrompt {
|
|||
LoginFocus::Token => {
|
||||
self.focus = LoginFocus::OK;
|
||||
}
|
||||
LoginFocus::OK => self.attempt(),
|
||||
LoginFocus::OK => self.attempt().await,
|
||||
},
|
||||
Key::Backspace => self.backspace(),
|
||||
Key::Tab => self.down(),
|
||||
Key::Up => {
|
||||
self.focus = match self.focus {
|
||||
LoginFocus::Hostname => LoginFocus::OK,
|
||||
|
@ -120,13 +149,7 @@ impl LoginPrompt {
|
|||
LoginFocus::OK => LoginFocus::Token,
|
||||
};
|
||||
}
|
||||
Key::Down => {
|
||||
self.focus = match self.focus {
|
||||
LoginFocus::Hostname => LoginFocus::Token,
|
||||
LoginFocus::Token => LoginFocus::OK,
|
||||
LoginFocus::OK => LoginFocus::Hostname,
|
||||
};
|
||||
}
|
||||
Key::Down => self.down(),
|
||||
Key::Char(c) => match self.focus {
|
||||
LoginFocus::Hostname => self.hostname.push(c),
|
||||
LoginFocus::Token => self.token.push(c),
|
||||
|
|
|
@ -8,6 +8,9 @@ use kkdisp::{
|
|||
Action, PlanLayers, View,
|
||||
};
|
||||
use login::LoginPrompt;
|
||||
use misskey::{
|
||||
websocket::WebSocketClientBuilder, HttpClient, WebSocketClient,
|
||||
};
|
||||
use tokio::sync::mpsc::{self, Receiver, Sender};
|
||||
mod login;
|
||||
|
||||
|
@ -17,6 +20,30 @@ async fn main() {
|
|||
std::process::exit(0);
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AuthDetail {
|
||||
pub hostname: String,
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
impl AuthDetail {
|
||||
pub async fn streaming(
|
||||
&self,
|
||||
) -> Result<WebSocketClient, anyhow::Error> {
|
||||
Ok(WebSocketClientBuilder::with_host(&self.hostname)
|
||||
.token(&self.token)
|
||||
.connect()
|
||||
.await?)
|
||||
}
|
||||
pub async fn normal(&self) -> Result<HttpClient, anyhow::Error> {
|
||||
Ok(HttpClient::builder(
|
||||
format!("https://{}", &self.hostname).as_str(),
|
||||
)
|
||||
.token(&self.token)
|
||||
.build()?)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Page {
|
||||
Login(LoginPrompt),
|
||||
}
|
||||
|
@ -31,6 +58,7 @@ impl Page {
|
|||
|
||||
pub struct AppView {
|
||||
recv: Receiver<Message>,
|
||||
auth: Option<AuthDetail>,
|
||||
page: Page,
|
||||
}
|
||||
|
||||
|
@ -46,35 +74,42 @@ impl Default for AppView {
|
|||
Self {
|
||||
recv,
|
||||
page: Page::Login(LoginPrompt::new()),
|
||||
auth: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Message {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl View for AppView {
|
||||
type Message = Message;
|
||||
|
||||
fn init(
|
||||
async fn init(
|
||||
&mut self,
|
||||
) -> std::result::Result<kkdisp::PlanLayers, anyhow::Error> {
|
||||
self.page.init()
|
||||
}
|
||||
|
||||
fn update(
|
||||
async fn update(
|
||||
&mut self,
|
||||
event: Event<Self::Message>,
|
||||
) -> std::result::Result<Action, anyhow::Error> {
|
||||
let page = &mut self.page;
|
||||
match page {
|
||||
Page::Login(login) => login.update(event),
|
||||
Page::Login(login) => login.update(event).await,
|
||||
}
|
||||
}
|
||||
|
||||
fn query(&mut self) -> Option<Self::Message> {
|
||||
match self.recv.try_recv() {
|
||||
Ok(msg) => Some(msg),
|
||||
Err(_) => None,
|
||||
match &mut self.page {
|
||||
Page::Login(log) => match log.query() {
|
||||
Some(auth) => {
|
||||
self.auth = Some(auth);
|
||||
None
|
||||
}
|
||||
None => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue