Skip to content

Commit c2c8a24

Browse files
authored
Merge pull request xch-dev#574 from dkackman/options-ui
Options UI
2 parents cc4f53c + a668879 commit c2c8a24

32 files changed

+2621
-1098
lines changed

crates/sage-api/endpoints.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"resync_cat": true,
8585
"update_cat": true,
8686
"update_did": true,
87+
"update_option": true,
8788
"update_nft": true,
8889
"update_nft_collection": true,
8990
"redownload_nft": true,

crates/sage-api/src/records/nft.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub struct NftRecord {
2525
pub edition_number: Option<u32>,
2626
pub edition_total: Option<u32>,
2727
pub icon_url: Option<String>,
28+
pub created_timestamp: Option<u64>,
2829
}
2930

3031
#[derive(Debug, Clone, Serialize, Deserialize)]

crates/sage-api/src/records/option.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ pub struct OptionRecord {
1313
pub amount: Amount,
1414
pub underlying_asset: Asset,
1515
pub underlying_amount: Amount,
16+
pub underlying_coin_id: String,
1617
pub strike_asset: Asset,
1718
pub strike_amount: Amount,
1819
pub expiration_seconds: u64,
1920
pub created_height: Option<u32>,
21+
pub created_timestamp: Option<u64>,
2022
}

crates/sage-api/src/requests/actions.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ pub struct UpdateCat {
2222
#[cfg_attr(feature = "tauri", derive(specta::Type))]
2323
pub struct UpdateCatResponse {}
2424

25+
#[derive(Debug, Clone, Serialize, Deserialize)]
26+
#[cfg_attr(feature = "tauri", derive(specta::Type))]
27+
pub struct UpdateOption {
28+
pub option_id: String,
29+
pub visible: bool,
30+
}
31+
32+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
33+
#[cfg_attr(feature = "tauri", derive(specta::Type))]
34+
pub struct UpdateOptionResponse {}
35+
2536
#[derive(Debug, Clone, Serialize, Deserialize)]
2637
#[cfg_attr(feature = "tauri", derive(specta::Type))]
2738
pub struct UpdateDid {

crates/sage-api/src/requests/data.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,14 +234,35 @@ pub struct GetMinterDidIdsResponse {
234234
pub total: u32,
235235
}
236236

237-
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
237+
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
238+
#[cfg_attr(feature = "tauri", derive(specta::Type))]
239+
#[serde(rename_all = "snake_case")]
240+
pub enum OptionSortMode {
241+
#[default]
242+
Name,
243+
CreatedHeight,
244+
ExpirationSeconds,
245+
}
246+
247+
#[derive(Debug, Clone, Serialize, Deserialize)]
238248
#[cfg_attr(feature = "tauri", derive(specta::Type))]
239-
pub struct GetOptions {}
249+
pub struct GetOptions {
250+
pub offset: u32,
251+
pub limit: u32,
252+
#[serde(default)]
253+
pub sort_mode: OptionSortMode,
254+
#[serde(default)]
255+
pub ascending: bool,
256+
pub find_value: Option<String>,
257+
#[serde(default)]
258+
pub include_hidden: bool,
259+
}
240260

241261
#[derive(Debug, Clone, Serialize, Deserialize)]
242262
#[cfg_attr(feature = "tauri", derive(specta::Type))]
243263
pub struct GetOptionsResponse {
244264
pub options: Vec<OptionRecord>,
265+
pub total: u32,
245266
}
246267

247268
#[derive(Debug, Clone, Serialize, Deserialize)]

crates/sage-database/src/tables/assets/option.rs

Lines changed: 217 additions & 98 deletions
Large diffs are not rendered by default.

crates/sage-database/src/tables/files.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ async fn candidates_for_download(
194194
WHERE data IS NULL
195195
AND (last_checked_timestamp IS NULL OR unixepoch() - last_checked_timestamp >= ?)
196196
AND failed_attempts < ?
197-
ORDER BY last_checked_timestamp ASC
198197
LIMIT ?
199198
",
200199
check_every_seconds,

crates/sage/src/endpoints/actions.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ use clvmr::Allocator;
88
use sage_api::{
99
IncreaseDerivationIndex, IncreaseDerivationIndexResponse, RedownloadNft, RedownloadNftResponse,
1010
ResyncCat, ResyncCatResponse, UpdateCat, UpdateCatResponse, UpdateDid, UpdateDidResponse,
11-
UpdateNft, UpdateNftCollection, UpdateNftCollectionResponse, UpdateNftResponse,
11+
UpdateNft, UpdateNftCollection, UpdateNftCollectionResponse, UpdateNftResponse, UpdateOption,
12+
UpdateOptionResponse,
1213
};
1314
use sage_assets::DexieCat;
1415
use sage_database::{Asset, AssetKind, Derivation};
1516
use sage_wallet::SyncCommand;
1617

17-
use crate::{parse_asset_id, parse_collection_id, parse_did_id, parse_nft_id, Error, Result, Sage};
18+
use crate::{
19+
parse_asset_id, parse_collection_id, parse_did_id, parse_nft_id, parse_option_id, Error,
20+
Result, Sage,
21+
};
1822

1923
impl Sage {
2024
pub async fn resync_cat(&self, req: ResyncCat) -> Result<ResyncCatResponse> {
@@ -69,6 +73,22 @@ impl Sage {
6973
Ok(UpdateCatResponse {})
7074
}
7175

76+
pub async fn update_option(&self, req: UpdateOption) -> Result<UpdateOptionResponse> {
77+
let wallet = self.wallet()?;
78+
79+
let option_id = parse_option_id(req.option_id)?;
80+
81+
let Some(mut asset) = wallet.db.asset(option_id).await? else {
82+
return Err(Error::MissingDid(option_id));
83+
};
84+
85+
asset.is_visible = req.visible;
86+
87+
wallet.db.update_asset(asset).await?;
88+
89+
Ok(UpdateOptionResponse {})
90+
}
91+
7292
pub async fn update_did(&self, req: UpdateDid) -> Result<UpdateDidResponse> {
7393
let wallet = self.wallet()?;
7494

crates/sage/src/endpoints/data.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ use sage_api::{
2424
GetSpendableCoinCountResponse, GetSyncStatus, GetSyncStatusResponse, GetToken,
2525
GetTokenResponse, GetTransaction, GetTransactionResponse, GetTransactions,
2626
GetTransactionsResponse, GetVersion, GetVersionResponse, NftCollectionRecord, NftData,
27-
NftRecord, NftSortMode as ApiNftSortMode, OptionRecord, PendingTransactionRecord,
28-
PerformDatabaseMaintenance, PerformDatabaseMaintenanceResponse, TokenRecord,
29-
TransactionCoinRecord, TransactionRecord,
27+
NftRecord, NftSortMode as ApiNftSortMode, OptionRecord, OptionSortMode as ApiOptionSortMode,
28+
PendingTransactionRecord, PerformDatabaseMaintenance, PerformDatabaseMaintenanceResponse,
29+
TokenRecord, TransactionCoinRecord, TransactionRecord,
3030
};
3131
use sage_database::{
32-
AssetFilter, CoinFilterMode, CoinSortMode, NftGroupSearch, NftRow, NftSortMode, Transaction,
33-
TransactionCoin,
32+
AssetFilter, CoinFilterMode, CoinSortMode, NftGroupSearch, NftRow, NftSortMode, OptionSortMode,
33+
Transaction, TransactionCoin,
3434
};
3535
use sage_wallet::WalletError;
3636

@@ -400,12 +400,30 @@ impl Sage {
400400
Ok(GetMinterDidIdsResponse { did_ids, total })
401401
}
402402

403-
pub async fn get_options(&self, _req: GetOptions) -> Result<GetOptionsResponse> {
403+
pub async fn get_options(&self, req: GetOptions) -> Result<GetOptionsResponse> {
404404
let wallet = self.wallet()?;
405405

406+
let sort_mode = match req.sort_mode {
407+
ApiOptionSortMode::Name => OptionSortMode::Name,
408+
ApiOptionSortMode::CreatedHeight => OptionSortMode::CreatedHeight,
409+
ApiOptionSortMode::ExpirationSeconds => OptionSortMode::ExpirationSeconds,
410+
};
411+
406412
let mut options = Vec::new();
407413

408-
for row in wallet.db.owned_options().await? {
414+
let (rows, total) = wallet
415+
.db
416+
.owned_options(
417+
req.limit,
418+
req.offset,
419+
sort_mode,
420+
req.ascending,
421+
req.find_value,
422+
req.include_hidden,
423+
)
424+
.await?;
425+
426+
for row in rows {
409427
options.push(OptionRecord {
410428
launcher_id: Address::new(row.asset.hash, "option".to_string()).encode()?,
411429
name: row.asset.name,
@@ -416,14 +434,16 @@ impl Sage {
416434
amount: Amount::u64(row.coin_row.coin.amount),
417435
underlying_asset: self.encode_asset(row.underlying_asset)?,
418436
underlying_amount: Amount::u64(row.underlying_amount),
437+
underlying_coin_id: hex::encode(row.underlying_coin_id),
419438
strike_asset: self.encode_asset(row.strike_asset)?,
420439
strike_amount: Amount::u64(row.strike_amount),
421440
expiration_seconds: row.expiration_seconds,
422441
created_height: row.coin_row.created_height,
442+
created_timestamp: row.coin_row.created_timestamp,
423443
});
424444
}
425445

426-
Ok(GetOptionsResponse { options })
446+
Ok(GetOptionsResponse { options, total })
427447
}
428448

429449
pub async fn get_option(&self, req: GetOption) -> Result<GetOptionResponse> {
@@ -446,10 +466,12 @@ impl Sage {
446466
amount: Amount::u64(row.coin_row.coin.amount),
447467
underlying_asset: self.encode_asset(row.underlying_asset)?,
448468
underlying_amount: Amount::u64(row.underlying_amount),
469+
underlying_coin_id: hex::encode(row.underlying_coin_id),
449470
strike_asset: self.encode_asset(row.strike_asset)?,
450471
strike_amount: Amount::u64(row.strike_amount),
451472
expiration_seconds: row.expiration_seconds,
452473
created_height: row.coin_row.created_height,
474+
created_timestamp: row.coin_row.created_timestamp,
453475
};
454476

455477
Ok(GetOptionResponse {
@@ -820,6 +842,7 @@ impl Sage {
820842
edition_number: metadata.as_ref().map(|m| m.edition_number as u32),
821843
edition_total: metadata.as_ref().map(|m| m.edition_total as u32),
822844
created_height: row.coin_row.created_height,
845+
created_timestamp: row.coin_row.created_timestamp,
823846
icon_url: row.asset.icon_url,
824847
})
825848
}

migrations/0002_options.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,5 @@ WHERE 1=1
162162
option_expiration_seconds IS NULL
163163
OR (option_creator_p2_puzzle_id IS NOT NULL AND unixepoch() >= option_expiration_seconds)
164164
);
165+
166+
CREATE INDEX idx_file_uris_timestamp_failed ON file_uris(last_checked_timestamp, failed_attempts);

0 commit comments

Comments
 (0)