Compare commits

...

11 Commits

Author SHA1 Message Date
MathieuG-P 8d88b59e3d bump version 2023-01-10 22:19:24 +01:00
MathieuG-P ae9d1dfc9b Merge pull request #97 from Zagrios/bugfix/unglow-apply-when-no-filter-change/90
bugfix/unglow-apply-when-no-filter-change/90
2023-01-10 22:06:27 +01:00
MathieuG-P 6930df940f compare first and new filter to know if changes 2023-01-10 22:05:25 +01:00
MathieuG-P fd523f4017 Merge pull request #95 from Zagrios/bugfix/error-when-no-internet/87
bugfix/error-when-no-internet/87
2023-01-10 21:38:02 +01:00
MathieuG-P 4c8f903256 handle no internet for mods and maps 2023-01-10 21:37:26 +01:00
MathieuG-P d2ba6aadc1 Merge pull request #94 from Zagrios/bugfix/infinite-map-loading/91
bugfix/infinite-map-loading/91
2023-01-10 20:21:34 +01:00
MathieuG-P 0023066e32 add text when no maps found 2023-01-10 20:21:00 +01:00
MathieuG-P 39bcf63e3c Merge pull request #93 from Zagrios/bugfix/supporter-button-not-work/89
bugfix/supporter-button-not-work/89
2023-01-10 20:05:41 +01:00
MathieuG-P 656f32e755 fix supporters not open + add missing key 2023-01-10 20:05:07 +01:00
MathieuG-P f66279980b Merge pull request #92 from Zagrios/bugfix/map-preview-behind-maps-download/88
bugfix/map-preview-behind-maps-download/88
2023-01-10 19:58:15 +01:00
MathieuG-P 1f65841e62 fix iframe view z index + rename iframe view file 2023-01-10 19:57:39 +01:00
15 changed files with 18967 additions and 185 deletions
+8 -3
View File
@@ -51,6 +51,7 @@
},
"mods": {
"loading-mods": "Loading mods...",
"no-internet": "No internet",
"buttons": {
"more-infos": "More info",
"install-or-update": "Install or update"
@@ -164,10 +165,12 @@
"shared": {
"errors": {
"titles": {
"operation-running": "Operation running"
"operation-running": "Operation running",
"no-internet": "No internet"
},
"msg": {
"operation-running": "Wait for the end of the current operation then start again."
"operation-running": "Wait for the end of the current operation then start again.",
"no-internet": "Check your connection and try again."
}
}
},
@@ -505,7 +508,9 @@
},
"download-maps": {
"search-btn": "Search",
"loading-maps": "Loading maps..."
"loading-maps": "Loading maps...",
"no-maps-found": "No maps found",
"no-internet": "No internet"
},
"mods-disclaimer":{
"title": "disclaimer",
+8 -3
View File
@@ -51,6 +51,7 @@
},
"mods": {
"loading-mods": "Cargando mods...",
"no-internet": "Sin internet",
"buttons": {
"more-infos": "Más información",
"install-or-update": "Instalar o actualizar"
@@ -164,10 +165,12 @@
"shared": {
"errors": {
"titles": {
"operation-running": "Operación en curso"
"operation-running": "Operación en curso",
"no-internet": "Sin internet"
},
"msg": {
"operation-running": "Espere a que termine la operación actual y vuelva a empezar."
"operation-running": "Espere a que termine la operación actual y vuelva a empezar.",
"no-internet": "Comprueba tu conexión a Internet e inténtalo de nuevo."
}
}
},
@@ -505,7 +508,9 @@
},
"download-maps": {
"search-btn": "buscar",
"loading-maps": "Cargando mapas..."
"loading-maps": "Cargando mapas...",
"no-maps-found": "No se encontraron mapas",
"no-internet": "Sin internet"
},
"mods-disclaimer":{
"title": "descargo de responsabilidad",
+8 -3
View File
@@ -51,6 +51,7 @@
},
"mods": {
"loading-mods": "Chargement des mods...",
"no-internet": "Pas d'internet",
"buttons": {
"more-infos": "Plus d'infos",
"install-or-update": "Installer ou mettre à jour"
@@ -164,10 +165,12 @@
"shared": {
"errors": {
"titles": {
"operation-running": "Opération en cours"
"operation-running": "Opération en cours",
"no-internet": "Pas d'internet"
},
"msg": {
"operation-running": "Attend la fin de l'opération en cours puis recommences."
"operation-running": "Attend la fin de l'opération en cours puis recommences.",
"no-internet": "Verifie t'a connexion internet et recommence."
}
}
},
@@ -505,7 +508,9 @@
},
"download-maps": {
"search-btn": "Rechercher",
"loading-maps": "Chargement des maps..."
"loading-maps": "Chargement des maps...",
"no-maps-found": "Aucune map trouvée",
"no-internet": "Pas d'internet"
},
"mods-disclaimer":{
"title": "avis de non-responsabilité",
+18877 -154
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -246,6 +246,7 @@
"react-range": "^1.8.14",
"react-router-dom": "^6.3.0",
"regedit": "^5.1.1",
"rfdc": "^1.3.0",
"rxjs": "^7.5.6",
"sanitize-filename": "^1.6.3",
"semver": "^7.3.8",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "bs-manager",
"version": "1.0.0-alpha.3",
"version": "1.0.0-alpha.4",
"description": "A foundation for scalable desktop apps",
"main": "./dist/main/main.js",
"author": {
@@ -12,6 +12,8 @@ import { MAP_SPECIFICITIES } from "renderer/partials/maps/map-general/map-specif
import { MAP_REQUIREMENTS } from "renderer/partials/maps/map-requirements/map-requirements"
import { MAP_DIFFICULTIES_COLORS } from "renderer/partials/maps/map-difficulties/map-difficulties-colors"
import { BsmButton } from "../shared/bsm-button.component"
import equal from "fast-deep-equal/es6";
import clone from "rfdc";
export type Props = {
className?: string,
@@ -28,6 +30,7 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange,
const t = useTranslation();
const [haveChanged, setHaveChanged] = useState(false);
const [firstFilter,] = useState(clone()(filter));
const firstRun = useRef(true);
const MIN_NPS = 0;
@@ -47,7 +50,8 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange,
firstRun.current = false;
return;
}
setHaveChanged(() => true);
console.log(filter, firstFilter);
setHaveChanged(() => !equal(filter, firstFilter));
}, [filter])
@@ -89,6 +93,9 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange,
if(max === MAX_NPS){
delete newFilter["maxNps"];
}
if(min === MIN_NPS){
delete newFilter["minNps"];
}
onChange(newFilter);
}
@@ -97,6 +104,9 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange,
if(max === MAX_DURATION){
delete newFilter["maxDuration"];
}
if(min === MIN_DURATION){
delete newFilter["minDuration"];
}
onChange(newFilter);
}
@@ -116,11 +126,17 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange,
enabledTags.add(tag);
}
onChange({
...filter,
enabledTags,
excludedTags
});
const newFilter = {...filter, enabledTags, excludedTags};
if(newFilter.enabledTags.size === 0){
delete newFilter["enabledTags"];
}
if(newFilter.excludedTags.size === 0){
delete newFilter["excludedTags"];
}
onChange(newFilter);
}
@@ -14,9 +14,11 @@ import { ModalComponent } from "renderer/services/modale.service";
import { BSVersion } from "shared/bs-version.interface";
import { BsvMapCharacteristic, BsvMapDetail, MapFilter, SearchOrder, SearchParams } from "shared/models/maps/beat-saver.model";
import BeatWaitingImg from "../../../../../assets/images/apngs/beat-waiting.png";
import BeatConflictImg from "../../../../../assets/images/apngs/beat-conflict.png";
import equal from "fast-deep-equal/es6";
import { ProgressBarService } from "renderer/services/progress-bar.service";
import { useTranslation } from "renderer/hooks/use-translation.hook";
import { OsDiagnosticService } from "renderer/services/os-diagnostic.service";
export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
@@ -24,6 +26,7 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
const mapsManager = MapsManagerService.getInstance();
const mapsDownloader = MapsDownloaderService.getInstance();
const progressBar = ProgressBarService.getInstance();
const os = OsDiagnosticService.getInstance();
const currentDownload = useObservable(mapsDownloader.currentMapDownload$);
const mapsInQueue = useObservable(mapsDownloader.mapsInQueue$);
@@ -34,6 +37,8 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
const [maps, setMaps] = useState<BsvMapDetail[]>([]);
const [sortOrder, setSortOrder] = useState<SearchOrder>(BSV_SORT_ORDER.at(0));
const [ownedMapHashs, setOwnedMapHashs] = useState<string[]>([]);
const [loading, setLoading] = useState(false);
const isOnline = useObservable(os.isOnline$);
const [searchParams, setSearchParams] = useState<SearchParams>({
sortOrder,
filter,
@@ -73,7 +78,8 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
}, [])
const loadMaps = (params: SearchParams) => {
beatSaver.searchMaps(params).then((maps => setMaps(prev => [...prev, ...maps])));
setLoading(() => true);
beatSaver.searchMaps(params).then((maps => setMaps(prev => [...prev, ...maps]))).finally(() => setLoading(() => false));
}
const extractMapDiffs = (map: BsvMapDetail): Map<BsvMapCharacteristic, ParsedMapDiff[]> => {
@@ -167,8 +173,8 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
<ul className="w-full grow flex content-start flex-wrap gap-2 px-2 overflow-y-scroll overflow-x-hidden scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900 z-0" >
{maps.length === 0 ? (
<div className="w-full h-full flex flex-col items-center justify-center">
<img className="w-32 h-32 spin-loading" src={BeatWaitingImg} alt=" "/>
<span className="text-lg">{t("modals.download-maps.loading-maps")}</span>
<img className={`w-32 h-32 ${loading && "spin-loading"}`} src={loading ? BeatWaitingImg : BeatConflictImg} alt=" "/>
<span className="text-lg">{t(loading ? "modals.download-maps.loading-maps" : isOnline ? "modals.download-maps.no-maps-found" : "modals.download-maps.no-internet")}</span>
</div>
) : (
<>
@@ -18,7 +18,7 @@ export function SupportersBlock({className, title, supporters}: Props) {
<div className={`mb-10 flex flex-col items-center ${className}`}>
<h2 className="uppercase text-3xl font-bold">{t(title)}</h2>
<div className="flex justify-center flex-wrap py-5 px-20">
{supporters.map(s => <SupporterItem supporter={s} delay={someDelay()}/>)}
{supporters.map(s => <SupporterItem key={crypto.randomUUID()} supporter={s} delay={someDelay()}/>)}
</div>
</div>
)
@@ -15,7 +15,7 @@ export function BsmIframeView() {
return (
<AnimatePresence>
{iframeUrl && (
<div className="top-0 absolute w-screen h-screen flex content-center items-center justify-center z-50">
<div className="top-0 absolute w-screen h-screen flex content-center items-center justify-center z-[150]">
<motion.span className="absolute w-full h-full bg-black top-0 right-0" initial={{opacity: 0}} animate={{opacity: .60}} exit={{opacity: 0}} transition={{duration: .2}}/>
<motion.div ref={ref} className="z-[1] w-[calc(100vw-250px)] h-[calc(100vh-250px)] shadow-black shadow-md rounded-md overflow-hidden bg-black" initial={{y: "100vh"}} animate={{y: 0}} exit={{y: "100vh"}}>
<iframe className="w-full h-full" src={iframeUrl}/>
@@ -7,6 +7,7 @@ import { ConfigurationService } from "renderer/services/configuration.service";
import { DefaultConfigKey } from "renderer/config/default-configuration.config";
import { BsmButton } from "renderer/components/shared/bsm-button.component";
import BeatWaitingImg from "../../../../../../assets/images/apngs/beat-waiting.png"
import BeatConflictImg from "../../../../../../assets/images/apngs/beat-conflict.png"
import { useObservable } from "renderer/hooks/use-observable.hook";
import { skip, filter } from "rxjs/operators";
import { Subscription } from "rxjs";
@@ -15,6 +16,7 @@ import { LinkOpenerService } from "renderer/services/link-opener.service";
import { useInView } from "framer-motion";
import { ModalExitCode, ModalService } from "renderer/services/modale.service";
import { ModsDisclaimerModal } from "renderer/components/modal/modal-types/mods-disclaimer-modal.component";
import { OsDiagnosticService } from "renderer/services/os-diagnostic.service";
export function ModsSlide({version, onDisclamerDecline}: {version: BSVersion, onDisclamerDecline: () => void}) {
@@ -24,6 +26,7 @@ export function ModsSlide({version, onDisclamerDecline}: {version: BSVersion, on
const configService = ConfigurationService.getInstance();
const linkOpener = LinkOpenerService.getInstance();
const modals = ModalService.getInsance();
const os = OsDiagnosticService.getInstance();
const ref = useRef(null);
const isVisible = useInView(ref, {amount: .5});
@@ -31,11 +34,13 @@ export function ModsSlide({version, onDisclamerDecline}: {version: BSVersion, on
const [modsInstalled, setModsInstalled] = useState(null as Map<string, Mod[]>);
const [modsSelected, setModsSelected] = useState([] as Mod[]);
const [moreInfoMod, setMoreInfoMod] = useState(null as Mod);
const isOnline = useObservable(os.isOnline$);
const installing = useObservable(modsManager.isInstalling$);
const t = useTranslation();
const downloadRef = useRef(null);
const [downloadWith, setDownloadWidth] = useState(0);
const modsToCategoryMap = (mods: Mod[]): Map<string, Mod[]> => {
if(!mods){ return new Map<string, Mod[]>(); }
@@ -69,6 +74,8 @@ export function ModsSlide({version, onDisclamerDecline}: {version: BSVersion, on
}
const loadMods = () => {
if(os.isOffline){ return; }
Promise.all([
modsManager.getAvailableMods(version),
modsManager.getInstalledMods(version)
@@ -84,7 +91,7 @@ export function ModsSlide({version, onDisclamerDecline}: {version: BSVersion, on
const subs: Subscription[] = [];
if(isVisible){
if(isVisible && isOnline){
const promise = new Promise<boolean>(async resolve => {
@@ -115,7 +122,7 @@ export function ModsSlide({version, onDisclamerDecline}: {version: BSVersion, on
subs.forEach(s => s.unsubscribe());
}
}, [isVisible, version]);
}, [isVisible, isOnline, version]);
useLayoutEffect(() => {
@@ -128,7 +135,7 @@ export function ModsSlide({version, onDisclamerDecline}: {version: BSVersion, on
return (
<div ref={ref} className='shrink-0 w-full h-full px-8 pb-7 flex justify-center'>
<div className='relative flex flex-col grow-0 bg-light-main-color-2 dark:bg-main-color-2 h-full w-full rounded-md shadow-black shadow-center overflow-hidden'>
{modsAvailable ? (
{isOnline && modsAvailable ? (
<>
<div className="overflow-scroll w-full min-h-0 scrollbar-thin scrollbar-thumb-neutral-900 scrollbar-thumb-rounded-full">
<ModsGrid modsMap={modsAvailable} installed={modsInstalled} modsSelected={modsSelected} onModChange={handleModChange} moreInfoMod={moreInfoMod} onWantInfos={handleMoreInfo}/>
@@ -142,8 +149,8 @@ export function ModsSlide({version, onDisclamerDecline}: {version: BSVersion, on
</>
) : (
<div className="w-full h-full flex flex-col items-center justify-center">
<img className="w-32 h-32 spin-loading" src={BeatWaitingImg} alt=" "/>
<span className="text-xl mt-3 h-0 italic">{t("pages.version-viewer.mods.loading-mods")}</span>
<img className={`w-32 h-32 ${isOnline && "spin-loading"}`} src={isOnline ? BeatWaitingImg : BeatConflictImg} alt=" "/>
<span className="text-xl mt-3 h-0 italic">{t(isOnline ? "pages.version-viewer.mods.loading-mods" : "pages.version-viewer.mods.no-internet")}</span>
</div>
)}
</div>
@@ -294,7 +294,7 @@ export function SettingsPage() {
<SettingContainer title="pages.settings.patreon.title" description="pages.settings.patreon.description">
<div className="flex gap-2">
<BsmButton className="flex w-fit rounded-md h-8 px-2 font-bold py-1 whitespace-nowrap !bg-red-500 !text-white" text="pages.settings.patreon.buttons.support" withBar={false} onClick={openSupportPage}/>
<BsmButton className="flex w-fit rounded-md h-8 px-2 font-bold py-1 !text-white" withBar={false} text="pages.settings.patreon.buttons.supporters" color="#6c5ce7" onClick={() => toogleShowSupporters}/>
<BsmButton className="flex w-fit rounded-md h-8 px-2 font-bold py-1 !text-white" withBar={false} text="pages.settings.patreon.buttons.supporters" color="#6c5ce7" onClick={toogleShowSupporters}/>
</div>
<SettingContainer className="mt-3" description="pages.settings.discord.description">
<div className="flex gap-2">
@@ -10,6 +10,7 @@ import { ProgressionInterface } from "shared/models/progress-bar";
import { IpcService } from "./ipc.service";
import { ModalExitCode, ModalService } from "./modale.service";
import { NotificationService, NotificationType } from "./notification.service";
import { OsDiagnosticService } from "./os-diagnostic.service";
import { ProgressBarService } from "./progress-bar.service";
export class BsModsManagerService {
@@ -22,6 +23,7 @@ export class BsModsManagerService {
private readonly progressBar: ProgressBarService;
private readonly modals: ModalService;
private readonly notifications: NotificationService;
private readonly os: OsDiagnosticService;
public readonly isInstalling$: BehaviorSubject<boolean> = new BehaviorSubject(false);
public readonly isUninstalling$: BehaviorSubject<boolean> = new BehaviorSubject(false);
@@ -36,17 +38,27 @@ export class BsModsManagerService {
this.progressBar = ProgressBarService.getInstance();
this.modals = ModalService.getInsance();
this.notifications = NotificationService.getInstance();
this.os = OsDiagnosticService.getInstance();
}
public getAvailableMods(version: BSVersion): Promise<Mod[]>{
public async getAvailableMods(version: BSVersion): Promise<Mod[]>{
return this.ipcService.send<Mod[], BSVersion>("get-available-mods", {args: version}).then(res => res.data);
}
public getInstalledMods(version: BSVersion): Promise<Mod[]>{
public async getInstalledMods(version: BSVersion): Promise<Mod[]>{
return this.ipcService.send<Mod[], BSVersion>("get-installed-mods", {args: version}).then(res => res.data);
}
public installMods(mods: Mod[], version: BSVersion): Promise<void>{
if(this.os.isOffline){
this.notifications.notifyError({
title: "notifications.shared.errors.titles.no-internet",
desc: "notifications.shared.errors.msg.no-internet"
});
return new Promise(res => res());
}
if(!this.progressBar.require()){ return new Promise(res => res()); }
const progress$: Observable<ProgressionInterface> = this.ipcService.watch<ModInstallProgression>("mod-installed").pipe(map(res => {
@@ -9,7 +9,7 @@ export class OsDiagnosticService {
return OsDiagnosticService.instance;
}
private _isOnline$ = new BehaviorSubject(true);
private _isOnline$ = new BehaviorSubject(navigator.onLine);
private constructor(){
+3 -1
View File
@@ -12,7 +12,7 @@ import { NotificationOverlay } from "../components/notification/notification-ove
import { PageStateService } from "../services/page-state.service";
import { MapsPage } from "../pages/maps-page.component";
import "tailwindcss/tailwind.css";
import { BsmIframeView } from "../components/shared/bsm-map-preview.component";
import { BsmIframeView } from "../components/shared/iframe-view.component";
import 'tippy.js/dist/tippy.css';
import { MapsManagerService } from "renderer/services/maps-manager.service";
import { PlaylistsManagerService } from "renderer/services/playlists-manager.service";
@@ -20,6 +20,7 @@ import { ModelsManagerService } from "renderer/services/models-manager.service";
import { NotificationService } from "renderer/services/notification.service";
import { timer } from "rxjs";
import { ConfigurationService } from "renderer/services/configuration.service";
import { OsDiagnosticService } from "renderer/services/os-diagnostic.service";
export default function App() {
@@ -30,6 +31,7 @@ export default function App() {
const models = ModelsManagerService.getInstance();
const notification = NotificationService.getInstance();
const config = ConfigurationService.getInstance();
const os = OsDiagnosticService.getInstance();
const location = useLocation();
const navigate = useNavigate();