Skip to content

Commit

Permalink
Merge pull request #3 from Kensaa/local_profiles
Browse files Browse the repository at this point in the history
Local profiles
  • Loading branch information
Kensaa authored Jan 13, 2024
2 parents c645f6d + fbc6881 commit df2d8d5
Show file tree
Hide file tree
Showing 18 changed files with 987 additions and 399 deletions.
633 changes: 382 additions & 251 deletions launcher/electron/electron.ts

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions launcher/electron/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as fs from 'fs'
import * as path from 'path'
import * as https from 'https'
import { get as httpGet } from 'http'
import { get as httpsGet } from 'https'
import { createHash } from 'crypto'
import fetch from 'electron-fetch'

Expand All @@ -19,15 +20,14 @@ export function download(address: string, filepath: string) {
fs.writeFileSync(filepath, '')
}
const file = fs.createWriteStream(filepath)
https
.get(address, res => {
res.pipe(file)
file.on('finish', () => {
file.close()
resolve()
})
const get = address.startsWith('https') ? httpsGet : httpGet
get(address, res => {
res.pipe(file)
file.on('finish', () => {
file.close()
resolve()
})
.on('error', err => reject(err))
}).on('error', err => reject(err))
})
}

Expand Down
2 changes: 1 addition & 1 deletion launcher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "A Minecraft launcher with auto-update feature to facilitate playing modded minecraft",
"author": "Kensa",
"private": true,
"version": "2.5.0",
"version": "3.0.0",
"main": "dist-electron/electron.js",
"scripts": {
"dev": "vite",
Expand Down
38 changes: 37 additions & 1 deletion launcher/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ import { Modal } from 'react-bootstrap'

import Home from './pages/Home'
import Settings from './pages/Settings'
import ServerManager from './pages/ServerManager'
import ProfileManager from './pages/ProfileManager'

export default function App() {
const [overlay, setOverlay] = useState<JSX.Element | undefined>(undefined)
const [settingsShown, setSettingsShown] = useState<boolean>(false)
const [serverManagerShown, setServerManagerShown] = useState<boolean>(false)
const [profileManagerShown, setProfileManagerShown] =
useState<boolean>(false)

return (
<div className='w-100 h-100 d-flex'>
Expand All @@ -20,7 +25,38 @@ export default function App() {
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Settings hide={() => setSettingsShown(false)} />
<Settings
hide={() => setSettingsShown(false)}
showServerManager={() => setServerManagerShown(true)}
showProfileManager={() => setProfileManagerShown(true)}
/>
</Modal.Body>
</Modal>

<Modal
show={serverManagerShown}
onHide={() => setServerManagerShown(false)}
>
<Modal.Header closeButton>
<Modal.Title style={{ color: 'black' }}>
Server Manager
</Modal.Title>
</Modal.Header>
<Modal.Body>
<ServerManager />
</Modal.Body>
</Modal>
<Modal
show={profileManagerShown}
onHide={() => setProfileManagerShown(false)}
>
<Modal.Header closeButton>
<Modal.Title style={{ color: 'black' }}>
Local Profile Manager
</Modal.Title>
</Modal.Header>
<Modal.Body>
<ProfileManager />
</Modal.Body>
</Modal>
</div>
Expand Down
6 changes: 2 additions & 4 deletions launcher/src/components/HomeHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import { SlidersHorizontal } from 'lucide-react'
import { Button } from 'react-bootstrap'
import ProfilePicker, { ProfilePickerProps } from './ProfilePicker'
import ProfilePicker from './ProfilePicker'
import UserElement from './UserElement'

export interface HomeHeaderProps {
style?: React.CSSProperties
className?: string
profileProps: ProfilePickerProps
setOverlay: (overlay: JSX.Element | undefined) => void
setSettingsShown: (show: boolean) => void
}

export default function HomeHeader({
style,
className,
profileProps,
setOverlay,
setSettingsShown
}: HomeHeaderProps) {
Expand All @@ -27,7 +25,7 @@ export default function HomeHeader({
style={style}
>
<UserElement setOverlay={setOverlay} />
<ProfilePicker {...profileProps} />
<ProfilePicker />
<Button
variant='light'
onClick={() => {
Expand Down
11 changes: 11 additions & 0 deletions launcher/src/components/LoadingSpinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Spinner } from 'react-bootstrap'

export default function LoadingSpinner() {
return (
<div style={{ color: 'white' }}>
<Spinner animation='border' role='status'>
<span className='visually-hidden'>Loading...</span>
</Spinner>
</div>
)
}
22 changes: 14 additions & 8 deletions launcher/src/components/ProfileElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import craftingtable from '../img/craftingtable.png'
import furnace from '../img/furnace.png'

interface ProfileElementProps {
profile: Profile | undefined
profile?: Profile
}

export default function ProfileElement({ profile }: ProfileElementProps) {
Expand All @@ -18,12 +18,6 @@ export default function ProfileElement({ profile }: ProfileElementProps) {
)
}

let versionString = profile.version.mc
if (profile.version.forge) {
let forge = profile.version.forge
forge = forge.substring(0, forge.lastIndexOf('-'))
versionString = forge
}
return (
<div className='d-flex flex-row align-items-center'>
<img
Expand All @@ -35,8 +29,20 @@ export default function ProfileElement({ profile }: ProfileElementProps) {
<h6 style={{ marginBottom: '0px', color: 'white' }}>
{profile.name}
</h6>
<span style={{ color: 'white' }}>{versionString}</span>
<span style={{ color: 'white' }}>
{getVersionString(profile.version)}
</span>
</div>
</div>
)
}

function getVersionString(version: Profile['version']) {
let versionString = version.mc
if (version.forge) {
let forge = version.forge
forge = forge.substring(0, forge.lastIndexOf('-'))
versionString = forge
}
return versionString
}
99 changes: 59 additions & 40 deletions launcher/src/components/ProfilePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,65 +3,84 @@ import { Dropdown, Spinner } from 'react-bootstrap'

import { Profile } from '../types'
import ProfileElement from './ProfileElement'
import {
useIsFetching,
useProfiles,
useSelectedProfile
} from '../stores/profiles'
import LoadingSpinner from './LoadingSpinner'

export interface ProfilePickerProps {
profiles: Profile[] | undefined
loading: boolean
selectedProfile: number
setSelectedProfile: (index: number) => void
}
export default function ProfilePicker() {
const profiles = useProfiles()
const fetching = useIsFetching()
const { selectedProfile, setSelectedProfile } = useSelectedProfile()

export default function ProfilePicker({
profiles,
loading,
selectedProfile,
setSelectedProfile
}: ProfilePickerProps) {
const selectProfile = (index: number) => {
setSelectedProfile(index)
ipcRenderer.send('set-selected-profile', index)
const selectProfile = (profile: [string, number]) => {
setSelectedProfile(profile)
ipcRenderer.send('set-selected-profile', profile)
}

const currentServer = profiles[selectedProfile[0]] ?? []
const profile = currentServer[selectedProfile[1]] ?? undefined

return (
<div
style={{ maxWidth: '400px' }}
className='d-flex flex-column align-items-center'
>
<Dropdown className='w-100 h-100'>
<Dropdown.Toggle
disabled={!profiles?.length}
disabled={!currentServer.length || fetching}
style={{ width: '350px' }}
className='d-flex flex-column align-items-center'
variant={!profiles?.length ? 'danger' : 'transparent'}
variant={
!currentServer.length && !fetching
? 'danger'
: 'transparent'
}
>
{loading ? (
<div>
<Spinner animation='border' role='status'>
<span className='visually-hidden'>
Loading...
</span>
</Spinner>
</div>
{fetching ? (
<LoadingSpinner />
) : (
<ProfileElement
profile={
profiles ? profiles[selectedProfile] : undefined
}
/>
<ProfileElement profile={profile} />
)}
</Dropdown.Toggle>
<Dropdown.Menu className='w-100' style={{ zIndex: 99999 }}>
{profiles &&
profiles.map((profile, index) => (
<Dropdown.Item
key={index}
onClick={() => selectProfile(index)}
>
<ProfileElement profile={profile} />
</Dropdown.Item>
))}
<Dropdown.Menu className='w-100'>
{Object.entries(profiles).map(
([server, profiles], serverIndex) => {
if (!profiles.length) return null
return (
<div key={serverIndex}>
<Divider text={server} />
{profiles.map((profile, profileIndex) => (
<Dropdown.Item
key={
serverIndex + ',' + profileIndex
}
onClick={() =>
selectProfile([
server,
profileIndex
])
}
>
<ProfileElement profile={profile} />
</Dropdown.Item>
))}
</div>
)
}
)}
</Dropdown.Menu>
</Dropdown>
</div>
)
}

function Divider({ text }: { text: string }) {
return (
<div className='d-flex flex-row align-items-center justify-content-center user-select-none mt-3'>
<label style={{ color: 'white' }}>{text}</label>
</div>
)
}
4 changes: 2 additions & 2 deletions launcher/src/components/UserElement.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import authStore from '../stores/auth'
import { useAuth } from '../stores/auth'
import { Button, Dropdown, DropdownButton } from 'react-bootstrap'
import { User, UserPlus } from 'lucide-react'

Expand All @@ -9,7 +9,7 @@ export default function UserElement({
}: {
setOverlay: (setOverlay: JSX.Element | undefined) => void
}) {
const auth = authStore(state => ({ ...state }))
const auth = useAuth()
const login = () => {
setOverlay(<TaskOverlay />)
auth.connect().then(() => setOverlay(undefined))
Expand Down
Loading

0 comments on commit df2d8d5

Please sign in to comment.