examples_fxa_client/
send_tab.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use clap::{Args, Subcommand};
6use fxa_client::{FirefoxAccount, IncomingDeviceCommand};
7
8use crate::{persist_fxa_state, Result};
9
10#[derive(Args)]
11pub struct SendTabArgs {
12    #[command(subcommand)]
13    command: Command,
14}
15
16#[derive(Subcommand)]
17enum Command {
18    /// Perform a single poll for tabs sent to this device
19    Poll,
20    /// Send a tab to another device
21    Send {
22        /// Device ID (use the `devices` command to list)
23        device_id: String,
24        title: String,
25        url: String,
26    },
27    /// Close an open tab on another device
28    Close {
29        device_id: String,
30        urls: Vec<String>,
31    },
32}
33
34pub fn run(account: &FirefoxAccount, args: SendTabArgs) -> Result<()> {
35    match args.command {
36        Command::Poll => poll(account),
37        Command::Send {
38            device_id,
39            title,
40            url,
41        } => send(account, device_id, title, url),
42        Command::Close { device_id, urls } => close(account, device_id, urls),
43    }
44}
45
46fn poll(account: &FirefoxAccount) -> Result<()> {
47    println!("Polling for send-tab events.  Ctrl-C to cancel");
48    loop {
49        let events = account.poll_device_commands().unwrap_or_default(); // Ignore 404 errors for now.
50        persist_fxa_state(account)?;
51        if !events.is_empty() {
52            for e in events {
53                match e {
54                    IncomingDeviceCommand::TabReceived { sender, payload } => {
55                        let tab = &payload.entries[0];
56                        match sender {
57                            Some(ref d) => {
58                                println!("Tab received from {}: {}", d.display_name, tab.url)
59                            }
60                            None => println!("Tab received: {}", tab.url),
61                        };
62                    }
63                    IncomingDeviceCommand::TabsClosed { .. } => continue,
64                }
65            }
66        }
67    }
68}
69
70fn send(account: &FirefoxAccount, device_id: String, title: String, url: String) -> Result<()> {
71    account.send_single_tab(&device_id, &title, &url)?;
72    println!("Tab sent!");
73    Ok(())
74}
75
76fn close(account: &FirefoxAccount, device_id: String, urls: Vec<String>) -> Result<()> {
77    account.close_tabs(&device_id, urls)?;
78    println!("Tabs closed!");
79    Ok(())
80}