dtmm: Add link to open mod on Nexus
All checks were successful
lint/clippy Checking for common mistakes and opportunities for code improvement
build/msvc Build for the target platform: msvc
build/linux Build for the target platform: linux
All checks were successful
lint/clippy Checking for common mistakes and opportunities for code improvement
build/msvc Build for the target platform: msvc
build/linux Build for the target platform: linux
Closes #157.
This commit is contained in:
parent
52959a3d5d
commit
57771617ff
6 changed files with 84 additions and 3 deletions
|
@ -19,6 +19,7 @@
|
|||
- dtmm: fetch cover image for Nexus mods
|
||||
- dtmm: fetch file version for Nexus mods
|
||||
- dtmm: handle `nxm://` URIs via IPC and import the corresponding mod
|
||||
- dtmm: Add button to open mod on nexusmods.com
|
||||
|
||||
=== Fixed
|
||||
|
||||
|
|
37
Cargo.lock
generated
37
Cargo.lock
generated
|
@ -920,6 +920,7 @@ dependencies = [
|
|||
"minijinja",
|
||||
"nexusmods",
|
||||
"oodle",
|
||||
"open",
|
||||
"path-slash",
|
||||
"sdk",
|
||||
"serde",
|
||||
|
@ -1882,6 +1883,25 @@ version = "2.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "is-docker"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-wsl"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
|
||||
dependencies = [
|
||||
"is-docker",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
|
@ -2340,6 +2360,17 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "open"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90878fb664448b54c4e592455ad02831e23a3f7e157374a8b95654731aac7349"
|
||||
dependencies = [
|
||||
"is-wsl",
|
||||
"libc",
|
||||
"pathdiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.59"
|
||||
|
@ -2478,6 +2509,12 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42"
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||
|
||||
[[package]]
|
||||
name = "pbkdf2"
|
||||
version = "0.11.0"
|
||||
|
|
|
@ -24,6 +24,7 @@ luajit2-sys = { path = "../../lib/luajit2-sys", version = "*" }
|
|||
minijinja = "1.0.10"
|
||||
nexusmods = { path = "../../lib/nexusmods", version = "*" }
|
||||
oodle = { path = "../../lib/oodle", version = "*" }
|
||||
open = "5.0.1"
|
||||
path-slash = "0.2.1"
|
||||
sdk = { path = "../../lib/sdk", version = "*" }
|
||||
serde = { version = "1.0.152", features = ["derive", "rc"] }
|
||||
|
|
|
@ -61,6 +61,8 @@ pub(crate) type InitialLoadResult = (Config, Vector<Arc<ModInfo>>);
|
|||
pub(crate) const ACTION_FINISH_LOAD_INITIAL: Selector<SingleUse<Option<InitialLoadResult>>> =
|
||||
Selector::new("dtmm.action.finish-load-initial");
|
||||
|
||||
pub(crate) const ACTION_OPEN_LINK: Selector<Arc<String>> = Selector::new("dtmm.action.open-link");
|
||||
|
||||
// A sub-selection of `State`'s fields that are required in `AsyncAction`s and that are
|
||||
// `Send + Sync`
|
||||
pub(crate) struct ActionState {
|
||||
|
@ -438,6 +440,20 @@ impl AppDelegate<State> for Delegate {
|
|||
|
||||
Handled::Yes
|
||||
}
|
||||
cmd if cmd.is(ACTION_OPEN_LINK) => {
|
||||
let url = cmd
|
||||
.get(ACTION_OPEN_LINK)
|
||||
.expect("command type matched but didn't contain the expected value");
|
||||
|
||||
if let Err(err) = open::that_detached(Arc::as_ref(url)) {
|
||||
tracing::error!(
|
||||
"{:?}",
|
||||
Report::new(err).wrap_err(format!("Failed to open url '{}'", url))
|
||||
);
|
||||
}
|
||||
|
||||
Handled::Yes
|
||||
}
|
||||
_ => Handled::No,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ macro_rules! make_color {
|
|||
}
|
||||
|
||||
make_color!(TOP_BAR_BACKGROUND_COLOR, COLOR_BG1);
|
||||
make_color!(LINK_COLOR, COLOR_ACCENT);
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub mod gruvbox_dark {
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::str::FromStr;
|
|||
use std::sync::Arc;
|
||||
|
||||
use druid::im::Vector;
|
||||
use druid::text::RichTextBuilder;
|
||||
use druid::widget::{
|
||||
Checkbox, CrossAxisAlignment, Either, Flex, Image, Label, LineBreaking, List,
|
||||
MainAxisAlignment, Maybe, Scroll, SizedBox, Split, Svg, SvgData, TextBox, ViewSwitcher,
|
||||
|
@ -16,9 +17,10 @@ use druid_widget_nursery::WidgetExt as _;
|
|||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::state::{
|
||||
ModInfo, NexusInfo, NexusInfoLens, State, View, ACTION_ADD_MOD, ACTION_SELECTED_MOD_DOWN,
|
||||
ACTION_SELECTED_MOD_UP, ACTION_SELECT_MOD, ACTION_SET_WINDOW_HANDLE, ACTION_START_CHECK_UPDATE,
|
||||
ACTION_START_DELETE_SELECTED_MOD, ACTION_START_DEPLOY, ACTION_START_RESET_DEPLOYMENT,
|
||||
ModInfo, NexusInfo, NexusInfoLens, State, View, ACTION_ADD_MOD, ACTION_OPEN_LINK,
|
||||
ACTION_SELECTED_MOD_DOWN, ACTION_SELECTED_MOD_UP, ACTION_SELECT_MOD, ACTION_SET_WINDOW_HANDLE,
|
||||
ACTION_START_CHECK_UPDATE, ACTION_START_DELETE_SELECTED_MOD, ACTION_START_DEPLOY,
|
||||
ACTION_START_RESET_DEPLOYMENT,
|
||||
};
|
||||
use crate::ui::theme::{self, ColorExt, COLOR_YELLOW_LIGHT};
|
||||
use crate::ui::widget::border::Border;
|
||||
|
@ -345,6 +347,28 @@ fn build_mod_details_info() -> impl Widget<State> {
|
|||
}
|
||||
});
|
||||
|
||||
let nexus_link = Maybe::or_empty(|| {
|
||||
let link = Label::raw().lens(NexusInfo::id.map(
|
||||
|id| {
|
||||
let url = format!("https://nexusmods.com/warhammer40kdarktide/mods/{}", id);
|
||||
let mut builder = RichTextBuilder::new();
|
||||
builder
|
||||
.push("Open on Nexusmods")
|
||||
.underline(true)
|
||||
.text_color(theme::LINK_COLOR)
|
||||
.link(ACTION_OPEN_LINK.with(Arc::new(url)));
|
||||
builder.build()
|
||||
},
|
||||
|_, _| {},
|
||||
));
|
||||
Flex::column()
|
||||
.cross_axis_alignment(CrossAxisAlignment::Start)
|
||||
.main_axis_alignment(MainAxisAlignment::Start)
|
||||
.with_child(link)
|
||||
.with_spacer(4.)
|
||||
})
|
||||
.lens(ModInfo::nexus.in_arc());
|
||||
|
||||
let details = Flex::column()
|
||||
.cross_axis_alignment(CrossAxisAlignment::Start)
|
||||
.main_axis_alignment(MainAxisAlignment::Start)
|
||||
|
@ -352,6 +376,7 @@ fn build_mod_details_info() -> impl Widget<State> {
|
|||
.with_spacer(4.)
|
||||
.with_child(summary)
|
||||
.with_spacer(4.)
|
||||
.with_child(nexus_link)
|
||||
.with_child(version_line)
|
||||
.with_spacer(4.)
|
||||
.with_child(categories)
|
||||
|
|
Loading…
Add table
Reference in a new issue