Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions apps/client/src/features/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@
"mobileHint": "Open this page on the machine running Tarkov to configure paths.",
"deleteScreenshots": "Delete screenshots after reading",
"deleteScreenshotsHint": "Sends each Tarkov screenshot to the Recycle Bin once its position has been read. Keeps the folder from filling up. Off by default.",
"source": {
"env": "from .env",
"manual": "manual",
"detected": "auto-detected",
"missing": "not found"
},
"missingTooltip": "Folder doesn't exist on disk yet.",
"placeholderGameDir": "D:\\EFT",
"placeholderScreenshotsDir": "Documents\\Escape from Tarkov\\Screenshots",
Expand Down
6 changes: 0 additions & 6 deletions apps/client/src/features/i18n/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@
"mobileHint": "Открой эту страницу на машине с Tarkov, чтобы настроить пути.",
"deleteScreenshots": "Удалять скриншоты после считывания",
"deleteScreenshotsHint": "Отправляет каждый скриншот Tarkov в корзину после считывания позиции. Не даёт папке разрастаться. По умолчанию выключено.",
"source": {
"env": "из .env",
"manual": "вручную",
"detected": "найдено автоматически",
"missing": "не найдено"
},
"missingTooltip": "Папка пока не существует.",
"placeholderGameDir": "D:\\EFT",
"placeholderScreenshotsDir": "Documents\\Escape from Tarkov\\Screenshots",
Expand Down
17 changes: 6 additions & 11 deletions apps/client/src/features/overlay/composables/useTrayIcon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,10 @@ const TRAY_ID = 'tarkov-checker-tray';
*
* The tray is the only control surface reachable while the game is fullscreen
* (the overlay can be hidden or click-through-locked behind it), so the menu
* holds ONLY window/session-level rescues and lifecycle: unlock, restore,
* always-on-top, the LAN-share shortcuts, quit. Map-layer settings (player
* follow, labels, ...) deliberately stay out — they belong to the LayerRail,
* which is reachable whenever you'd actually want to flip them. Left-click restores the
* window (Windows convention); right-click opens the menu. Since ✕ now parks
* the overlay in the tray (see overlay store `minimizeToTray`), "Quit" here is
* the canonical way to actually exit.
* holds window/session-level rescues and lifecycle only; map-layer settings
* live on the LayerRail. Left-click restores the window (Windows convention);
* right-click opens the menu. Since ✕ parks the overlay in the tray (see
* overlay store `minimizeToTray`), "Quit" here is the canonical way to exit.
*/
export function useTrayIcon(isTauri: boolean, overlayClickThrough: Ref<boolean>): void {
if (!isTauri) return;
Expand Down Expand Up @@ -134,10 +131,8 @@ export function useTrayIcon(isTauri: boolean, overlayClickThrough: Ref<boolean>)
})(),
});

// Conditional: only when an update is already known. Deliberately does
// NOT install from the tray — install = respawn = session killed, too
// destructive for an impulsive menu click. It restores the window with
// the banner visible; the install decision happens window-in-focus.
// Shows the window + banner instead of installing: install respawns the
// app — too destructive for a stray tray click.
const updateItem = labels.update
? await MenuItem.new({
id: 'update-available',
Expand Down
2 changes: 0 additions & 2 deletions apps/client/src/features/settings/SettingsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ const openSections = persistedRef(
</AccordionContent>
</AccordionPanel>
</Accordion>
<!-- Not a section on purpose: version + update controls are periphery,
not a peer of Hotkeys/Overlay (see the about-footer design review). -->
<AboutFooter />
</Drawer>
</template>
6 changes: 2 additions & 4 deletions apps/client/src/features/updater/components/AboutFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ const version = useAppVersion();
const updater = useUpdaterStore();
const { autoCheck, info, checking, installing, lastCheck } = storeToRefs(updater);

// "Up to date" settles for a moment, then the button returns to its idle
// label; errors stay until the next click (per the design review). Driven by
// the click completing — NOT by watching lastCheck, whose value doesn't
// change on a repeat "still up to date" outcome.
// Driven by the click completing — not by watching lastCheck, whose value
// doesn't change on a repeat "still up to date" outcome.
const showLatest = ref(false);
let latestTimer: ReturnType<typeof setTimeout> | undefined;
function flashUpToDate(): void {
Expand Down
38 changes: 28 additions & 10 deletions apps/desktop/src-tauri/src/server/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,27 +164,34 @@ pub fn detect_documents_dir() -> Option<String> {
Some(expand_env_vars(&raw))
}

/// BSG launcher writes the install location to one of these keys; try in
/// order. winreg auto-redirects WOW6432Node access.
/// Reads `InstallLocation` from the BSG launcher's standard uninstall entry
/// (32-bit view / native / per-user hives). A value whose directory exists
/// wins over a stale one.
pub fn detect_tarkov_game_dir() -> Option<String> {
use winreg::enums::{HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE};
use winreg::RegKey;
const UNINSTALL_EFT: &str =
r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\EscapeFromTarkov";
const UNINSTALL_EFT_WOW: &str =
r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\EscapeFromTarkov";
let candidates: &[(winreg::HKEY, &str)] = &[
(
HKEY_LOCAL_MACHINE,
r"SOFTWARE\WOW6432Node\Battlestate Games\EFT",
),
(HKEY_LOCAL_MACHINE, r"SOFTWARE\Battlestate Games\EFT"),
(HKEY_CURRENT_USER, r"Software\Battlestate Games\EFT"),
(HKEY_LOCAL_MACHINE, UNINSTALL_EFT_WOW),
(HKEY_LOCAL_MACHINE, UNINSTALL_EFT),
(HKEY_CURRENT_USER, UNINSTALL_EFT),
];
let mut first_found: Option<String> = None;
for (hive, path) in candidates {
if let Ok(key) = RegKey::predef(*hive).open_subkey(path) {
if let Ok(raw) = key.get_value::<String, _>("InstallLocation") {
return Some(expand_env_vars(&raw));
let expanded = expand_env_vars(&raw);
if Path::new(&expanded).is_dir() {
return Some(expanded);
}
first_found.get_or_insert(expanded);
}
}
}
None
first_found
}

fn expand_env_vars(value: &str) -> String {
Expand Down Expand Up @@ -287,4 +294,15 @@ mod tests {
fn paths_normalize_unc_forward_slash_returns_none() {
assert_eq!(normalize(Some("//server/share")), None);
}

/// Machine-dependent diagnostic, excluded from CI. Run manually on a box
/// with EFT installed: `cargo test detect_tarkov_live -- --ignored --nocapture`.
#[test]
#[ignore = "probes the real registry — run manually on a machine with EFT"]
fn detect_tarkov_live_probe() {
let detected = detect_tarkov_game_dir();
println!("detected game dir: {detected:?}");
println!("detected documents dir: {:?}", detect_documents_dir());
assert!(detected.is_some(), "no registry key yielded a game dir");
}
}