mirror of
https://github.com/Novattz/creamlinux-installer.git
synced 2026-05-02 04:52:03 -04:00
reflect votes in dialogs #22
This commit is contained in:
110
src/components/dialogs/SmokeAPIVotesDialog.tsx
Normal file
110
src/components/dialogs/SmokeAPIVotesDialog.tsx
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogHeader,
|
||||||
|
DialogBody,
|
||||||
|
DialogFooter,
|
||||||
|
DialogActions,
|
||||||
|
} from '@/components/dialogs'
|
||||||
|
import { Button } from '@/components/buttons'
|
||||||
|
import { Icon, info } from '@/components/icons'
|
||||||
|
import VotesDisplay, { GameVotes } from '@/components/common/VotesDisplay'
|
||||||
|
|
||||||
|
export interface SmokeAPIVotesDialogProps {
|
||||||
|
visible: boolean
|
||||||
|
gameId: string | null
|
||||||
|
gameTitle: string | null
|
||||||
|
onConfirm: () => void
|
||||||
|
onClose: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shown before installing SmokeAPI on a Proton game.
|
||||||
|
* Fetches and displays community votes for SmokeAPI specifically,
|
||||||
|
* then lets the user confirm or cancel the installation.
|
||||||
|
*/
|
||||||
|
const SmokeAPIVotesDialog: React.FC<SmokeAPIVotesDialogProps> = ({
|
||||||
|
visible,
|
||||||
|
gameId,
|
||||||
|
gameTitle,
|
||||||
|
onConfirm,
|
||||||
|
onClose,
|
||||||
|
}) => {
|
||||||
|
const [votes, setVotes] = useState<GameVotes | null>(null)
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!visible || !gameId) {
|
||||||
|
setVotes(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(true)
|
||||||
|
invoke<GameVotes[]>('get_game_votes', { gameId })
|
||||||
|
.then((results) => {
|
||||||
|
setVotes(results.find((v) => v.unlocker === 'smokeapi') ?? null)
|
||||||
|
})
|
||||||
|
.catch(() => setVotes(null))
|
||||||
|
.finally(() => setLoading(false))
|
||||||
|
}, [visible, gameId])
|
||||||
|
|
||||||
|
const hasVotes = votes && (votes.success > 0 || votes.fail > 0)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog visible={visible} onClose={onClose} size="small">
|
||||||
|
<DialogHeader onClose={onClose} hideCloseButton={true}>
|
||||||
|
<h3>Install SmokeAPI</h3>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<DialogBody>
|
||||||
|
<div className="smokeapi-votes-content">
|
||||||
|
<p className="smokeapi-votes-game">
|
||||||
|
<strong>{gameTitle}</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="smokeapi-votes-section">
|
||||||
|
<p className="smokeapi-votes-label">Community compatibility</p>
|
||||||
|
{loading ? (
|
||||||
|
<p className="smokeapi-votes-loading">Fetching votes...</p>
|
||||||
|
) : (
|
||||||
|
<VotesDisplay votes={votes} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!loading && !hasVotes && (
|
||||||
|
<div className="smokeapi-votes-notice">
|
||||||
|
<Icon name={info} variant="solid" size="md" />
|
||||||
|
<span>
|
||||||
|
No one has rated this game yet. You'll be able to submit a rating after
|
||||||
|
installing.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!loading && hasVotes && (
|
||||||
|
<div className="smokeapi-votes-notice">
|
||||||
|
<Icon name={info} variant="solid" size="sm" />
|
||||||
|
<span>
|
||||||
|
These ratings are from other CreamLinux users. Results may vary.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</DialogBody>
|
||||||
|
|
||||||
|
<DialogFooter>
|
||||||
|
<DialogActions>
|
||||||
|
<Button variant="secondary" onClick={onClose}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant="primary" onClick={onConfirm}>
|
||||||
|
Install anyway
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</DialogFooter>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SmokeAPIVotesDialog
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import React from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
@@ -8,10 +9,12 @@ import {
|
|||||||
} from '@/components/dialogs'
|
} from '@/components/dialogs'
|
||||||
import { Button } from '@/components/buttons'
|
import { Button } from '@/components/buttons'
|
||||||
import { Icon, info } from '@/components/icons'
|
import { Icon, info } from '@/components/icons'
|
||||||
|
import VotesDisplay, { GameVotes } from '@/components/common/VotesDisplay'
|
||||||
|
|
||||||
export interface UnlockerSelectionDialogProps {
|
export interface UnlockerSelectionDialogProps {
|
||||||
visible: boolean
|
visible: boolean
|
||||||
gameTitle: string
|
gameId: string | null
|
||||||
|
gameTitle: string | null
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
onSelectCreamLinux: () => void
|
onSelectCreamLinux: () => void
|
||||||
onSelectSmokeAPI: () => void
|
onSelectSmokeAPI: () => void
|
||||||
@@ -19,15 +22,39 @@ export interface UnlockerSelectionDialogProps {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unlocker Selection Dialog component
|
* Unlocker Selection Dialog component
|
||||||
* Allows users to choose between CreamLinux and SmokeAPI for native Linux games
|
* Allows users to choose between CreamLinux and SmokeAPI for native Linux games.
|
||||||
|
* Fetches and displays community vote data per unlocker.
|
||||||
*/
|
*/
|
||||||
const UnlockerSelectionDialog: React.FC<UnlockerSelectionDialogProps> = ({
|
const UnlockerSelectionDialog: React.FC<UnlockerSelectionDialogProps> = ({
|
||||||
visible,
|
visible,
|
||||||
|
gameId,
|
||||||
gameTitle,
|
gameTitle,
|
||||||
onClose,
|
onClose,
|
||||||
onSelectCreamLinux,
|
onSelectCreamLinux,
|
||||||
onSelectSmokeAPI,
|
onSelectSmokeAPI,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [creamVotes, setCreamVotes] = useState<GameVotes | null>(null)
|
||||||
|
const [smokeVotes, setSmokeVotes] = useState<GameVotes | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!visible || !gameId) {
|
||||||
|
setCreamVotes(null)
|
||||||
|
setSmokeVotes(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
invoke<GameVotes[]>('get_game_votes', { gameId })
|
||||||
|
.then((results) => {
|
||||||
|
setCreamVotes(results.find((v) => v.unlocker === 'creamlinux') ?? null)
|
||||||
|
setSmokeVotes(results.find((v) => v.unlocker === 'smokeapi') ?? null)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// Votes are non-critical — silently fall back to "No votes yet"
|
||||||
|
setCreamVotes(null)
|
||||||
|
setSmokeVotes(null)
|
||||||
|
})
|
||||||
|
}, [visible, gameId])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog visible={visible} onClose={onClose} size="medium">
|
<Dialog visible={visible} onClose={onClose} size="medium">
|
||||||
<DialogHeader onClose={onClose} hideCloseButton={true}>
|
<DialogHeader onClose={onClose} hideCloseButton={true}>
|
||||||
@@ -52,6 +79,7 @@ const UnlockerSelectionDialog: React.FC<UnlockerSelectionDialogProps> = ({
|
|||||||
Native Linux DLC unlocker. Works best with most native Linux games and provides
|
Native Linux DLC unlocker. Works best with most native Linux games and provides
|
||||||
better compatibility.
|
better compatibility.
|
||||||
</p>
|
</p>
|
||||||
|
<VotesDisplay votes={creamVotes} />
|
||||||
<Button variant="primary" onClick={onSelectCreamLinux} fullWidth>
|
<Button variant="primary" onClick={onSelectCreamLinux} fullWidth>
|
||||||
Install CreamLinux
|
Install CreamLinux
|
||||||
</Button>
|
</Button>
|
||||||
@@ -66,6 +94,7 @@ const UnlockerSelectionDialog: React.FC<UnlockerSelectionDialogProps> = ({
|
|||||||
Cross-platform DLC unlocker. Try this if CreamLinux doesn't work for your game.
|
Cross-platform DLC unlocker. Try this if CreamLinux doesn't work for your game.
|
||||||
Automatically fetches DLC information.
|
Automatically fetches DLC information.
|
||||||
</p>
|
</p>
|
||||||
|
<VotesDisplay votes={smokeVotes} />
|
||||||
<Button variant="secondary" onClick={onSelectSmokeAPI} fullWidth>
|
<Button variant="secondary" onClick={onSelectSmokeAPI} fullWidth>
|
||||||
Install SmokeAPI
|
Install SmokeAPI
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user