Files
modrinth/packages/app-lib/src/state/server_join_log.rs
T
734720e11e feat: instances v2 (#6431)
* feat: base of instances v2

* feat: use old profiles with compat layer

* prototype: instances v2

* fix: install_from using profile

* fix: skins migration fix

* fix: frontend still using profile path

* fix: add update proj multiselect guard

* fix: cargo fmt

* fix: content missing fields

* feat: break up app-lib/api/instance.rs

* fix: check_content_updates mismatch

* fix: updater modal cleanup w/new structure

* feat: better update all handling

* fix: remove preview_update_all

* fix: feedback on bulk update + lint

* fix: rem transitions

* fix: change to jsonb

* feat: app db backup after update

* fix: lint

* fix: sqlx prepare + use sqlx macros

* fix: lint

* fix: bugs

* feat: defuck the installing process up

* fix: bug of hell

* fix: shear

* fix: fmt

* fix: install progress spacing + change mc/content/overrides to bytes

* fix: lint

* fix: prepr

* fix: navtabs anim not working in app

* fix: worlds.vue improvements + browse page fixes

* feat: optimise queries + adapter fns

* fix: lint

* fix: lint

* feat: shared modrinth-content-management crate (#6469)

* feat: disable warnings setting

* feat: add instances shortcuts (#6329)

* Add modrinth://launch deep link to start a profile

Support external profile launching via modrinth://launch/{profile_path} for integrations such as Stream Deck.

* Change route to /launch/profile/{id} for future extensibility

* fix: ensure profile path is url decoded

* fix: URL-decode profile path from deep link

* fix: use urlencoding crate for URL decoding

* feat: implement app instance shortcuts

* feat: change windows shortcut creation to use windows api instead

* feat: implement creating a shortcut launching world/server

* format

* fmt

* fix multiline inline tables

* pnpm prepr

* feat: move create shortcut to last item

* refactor: split up shortcuts.rs for individual platforms

* refactor: turn profile launch url into url type

* use string literal and add safety comment

* pt2

* refactor: rename anything that's profile into instance

* update mac shortcut

---------

Co-authored-by: DJCheesusReal <134006619+DJCheesusReal@users.noreply.github.com>

---------

Co-authored-by: Truman Gao <106889354+tdgao@users.noreply.github.com>
Co-authored-by: DJCheesusReal <134006619+DJCheesusReal@users.noreply.github.com>
2026-06-25 21:19:29 +00:00

69 lines
1.5 KiB
Rust

use std::collections::HashMap;
use chrono::{DateTime, TimeZone, Utc};
#[derive(Default)]
pub struct JoinLogEntry {
pub instance_id: String,
pub host: String,
pub port: u16,
pub join_time: DateTime<Utc>,
}
impl JoinLogEntry {
pub async fn upsert(
&self,
exec: impl sqlx::Executor<'_, Database = sqlx::Sqlite>,
) -> crate::Result<()> {
let join_time = self.join_time.timestamp();
let instance_id = self.instance_id.as_str();
let host = self.host.as_str();
let port = i64::from(self.port);
sqlx::query!(
"
INSERT INTO join_log (instance_id, host, port, join_time)
VALUES (?, ?, ?, ?)
ON CONFLICT (instance_id, host, port) DO UPDATE SET
join_time = excluded.join_time
",
instance_id,
host,
port,
join_time,
)
.execute(exec)
.await?;
Ok(())
}
}
pub async fn get_joins(
instance_id: &str,
exec: impl sqlx::Executor<'_, Database = sqlx::Sqlite>,
) -> crate::Result<HashMap<(String, u16), DateTime<Utc>>> {
let joins = sqlx::query!(
"
SELECT host, port, join_time
FROM join_log
WHERE instance_id = ?
",
instance_id,
)
.fetch_all(exec)
.await?;
Ok(joins
.into_iter()
.map(|row| {
(
(row.host, row.port as u16),
Utc.timestamp_opt(row.join_time, 0)
.single()
.unwrap_or_else(Utc::now),
)
})
.collect())
}