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
9 changes: 9 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# v1.3.6

- Fix download progress display for direct HTTP downloads by parsing rclone stats output.
- Add Ready to Install filter (stored locally, not installed) with icons and tooltips.
- Keep toolbar controls and status text on a single line; set minimum window width to 1250px.
- Update popularity display to 5-star ratings with half stars.
- Ensure Installed filter reflects actual device installs only.
- Improve trailer fallback UI with thumbnail + YouTube logo and clearer messaging.

# v1.3.5

- Fix downloads on macOS without FUSE by falling back to direct HTTP download.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "apprenticevr",
"version": "1.3.5",
"version": "1.3.6",
"description": "An Electron application with React and TypeScript",
"main": "./out/main/index.js",
"author": "example.com",
Expand Down
7 changes: 4 additions & 3 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ function sendDependencyProgress(
async function createWindow(): Promise<void> {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1200,
minWidth: 1200,
width: 1250,
minWidth: 1250,
height: 900,
show: false,
autoHideMenuBar: true,
Expand All @@ -176,7 +176,7 @@ async function createWindow(): Promise<void> {
})

// Explicitly set minimum size to ensure constraint is enforced
mainWindow.setMinimumSize(1200, 900)
mainWindow.setMinimumSize(1250, 900)

mainWindow.on('ready-to-show', async () => {
if (mainWindow) {
Expand Down Expand Up @@ -723,6 +723,7 @@ app.whenReady().then(async () => {
return await downloadService.copyObbFolder(folderPath, deviceId)
})


// Validate that all IPC channels have handlers registered
const allHandled = typedIpcMain.validateAllHandlersRegistered()
if (!allHandled) {
Expand Down
12 changes: 12 additions & 0 deletions src/renderer/src/assets/games-view.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
margin-bottom: 8px;
padding-bottom: 8px;
border-bottom: 1px solid #e0e0e0;
Expand All @@ -51,11 +52,17 @@
display: flex;
align-items: center;
gap: 16px;
flex-wrap: nowrap;
}

.games-toolbar-left button {
white-space: nowrap;
}

.last-synced {
color: var(--colorNeutralForeground2);
font-size: 0.9em;
white-space: nowrap;
}

.game-count {
Expand Down Expand Up @@ -270,15 +277,20 @@
display: flex;
gap: 8px;
margin-left: 16px;
flex-wrap: nowrap;
}

.filter-buttons button {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
font-size: 0.85em;
background-color: #f8f9fa;
border: 1px solid #dadce0;
border-radius: 12px; /* More rounded */
cursor: pointer;
white-space: nowrap;
transition:
background-color 0.2s,
border-color 0.2s,
Expand Down
7 changes: 7 additions & 0 deletions src/renderer/src/assets/images/youtube-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 68 additions & 11 deletions src/renderer/src/components/GameDetailsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
BroomRegular as UninstallIcon
} from '@fluentui/react-icons'
import placeholderImage from '../assets/images/game-placeholder.png'
import youtubeLogo from '../assets/images/youtube-logo.svg'
import YouTube from 'react-youtube'
import { useGames } from '@renderer/hooks/useGames'

Expand Down Expand Up @@ -127,6 +128,43 @@ const useStyles = makeStyles({
paddingTop: '56.25%', // 16:9 aspect ratio
marginTop: tokens.spacingVerticalM
},
youtubeFallback: {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
display: 'grid',
placeItems: 'center',
backgroundColor: tokens.colorNeutralBackground2,
borderRadius: tokens.borderRadiusMedium,
overflow: 'hidden',
textAlign: 'center'
},
youtubeFallbackContent: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: tokens.spacingVerticalS,
padding: tokens.spacingVerticalM
},
youtubeFallbackThumb: {
width: '100%',
height: '100%',
objectFit: 'cover',
position: 'absolute',
inset: 0,
filter: 'brightness(0.45)'
},
youtubeFallbackLogo: {
width: '120px',
height: 'auto',
marginBottom: tokens.spacingVerticalS
},
youtubeFallbackOverlay: {
position: 'relative',
zIndex: 1
},
youtubePlayer: {
position: 'absolute',
top: 0,
Expand Down Expand Up @@ -552,17 +590,36 @@ const GameDetailsDialog: React.FC<GameDetailsDialogProps> = ({
{loadingVideo ? (
<Spinner size="tiny" label="Searching for trailer..." />
) : videoError && videoId ? (
<Text>
Trailer unavailable in-app.{' '}
<a
href={`https://www.youtube.com/watch?v=${videoId}`}
target="_blank"
rel="noreferrer"
>
Open on YouTube
</a>
.
</Text>
<div className={styles.youtubeContainer}>
<div className={styles.youtubeFallback}>
<img
className={styles.youtubeFallbackThumb}
src={`https://img.youtube.com/vi/${videoId}/hqdefault.jpg`}
alt="Trailer thumbnail"
/>
<div className={styles.youtubeFallbackOverlay}>
<div className={styles.youtubeFallbackContent}>
<img
className={styles.youtubeFallbackLogo}
src={youtubeLogo}
alt="YouTube"
/>
<Text weight="semibold">Trailer can’t play in-app</Text>
<Text size={200} style={{ color: tokens.colorNeutralForeground2 }}>
Some videos block embeds. Open it on YouTube instead.
</Text>
<Button
appearance="primary"
onClick={() =>
window.open(`https://www.youtube.com/watch?v=${videoId}`, '_blank')
}
>
Open on YouTube
</Button>
</div>
</div>
</div>
</div>
) : videoId ? (
<div className={styles.youtubeContainer}>
<YouTube
Expand Down
Loading