Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature-593] We can now delete duplicates maps #605

Merged
merged 1 commit into from
Oct 6, 2024
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
16 changes: 15 additions & 1 deletion assets/jsons/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"filters-btn": "Filter",
"dropdown": {
"export-maps": "Maps exportieren",
"delete-maps": "Maps löschen"
"delete-maps": "Maps löschen",
"delete-duplicate-maps": "Duplikate löschen"
}
},
"tabs": {
Expand Down Expand Up @@ -496,6 +497,14 @@
"one-click-install": {
"success": "Map-Installation abgeschlossen",
"error": "Ein Fehler ist während der Installation der Map aufgetreten."
},
"no-duplicates-maps": {
"title": "Keine Duplikate",
"msg": "Keine Karten wurden gelöscht"
},
"duplicates-maps-deleted": {
"title": "Duplikate gelöscht",
"msg": "Duplikate wurden gelöscht"
}
},
"playlists": {
Expand Down Expand Up @@ -690,6 +699,11 @@
"title": "\"Maps behalten\" kopiert die Maps aus dem geteilten Maps-Ordner in den Ordner der ausgewählten Version. Andernfalls gehen sie verloren."
},
"valid-btn": "Verknüpfung aufheben"
},
"delete-duplicate-maps": {
"title": "Map entfernen?",
"desc": "Nur die Karte \"{map}\" ist ein Duplikat. Bist du sicher, dass du sie löschen möchtest?",
"desc-plural": "Es wurden {nb} doppelte Karten gefunden. Bist du sicher, dass du sie löschen möchtest?"
}
},
"download-maps": {
Expand Down
16 changes: 15 additions & 1 deletion assets/jsons/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"filters-btn": "Filters",
"dropdown": {
"export-maps": "Export maps",
"delete-maps": "Delete maps"
"delete-maps": "Delete maps",
"delete-duplicate-maps": "Delete duplicates"
}
},
"tabs": {
Expand Down Expand Up @@ -503,6 +504,14 @@
"one-click-install": {
"success": "Map installation complete",
"error": "An error occurred while installing the map"
},
"no-duplicates-maps": {
"title": "No Duplicates",
"msg": "No maps were deleted"
},
"duplicates-maps-deleted": {
"title": "Duplicates Deleted",
"msg": "Duplicates were deleted"
}
},
"playlists": {
Expand Down Expand Up @@ -697,6 +706,11 @@
"title": "Keeping maps will copy all maps from the shared folder to the current version after unlinking. Maps will not be lost if this is disabled."
},
"valid-btn": "Unlink maps"
},
"delete-duplicate-maps": {
"title": "Delete maps?",
"desc": "Only the map \"{map}\" is a duplicate. Are you sure you want to delete it?",
"desc-plural": "{nb} duplicate maps have been found. Are you sure you want to delete them?"
}
},
"download-maps": {
Expand Down
16 changes: 15 additions & 1 deletion assets/jsons/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"filters-btn": "Filtros",
"dropdown": {
"export-maps": "Exportar mapas",
"delete-maps": "Borrar mapas"
"delete-maps": "Borrar mapas",
"delete-duplicate-maps": "Borrar duplicados"
}
},
"tabs": {
Expand Down Expand Up @@ -496,6 +497,14 @@
"one-click-install": {
"success": "Instalación del mapa completada",
"error": "Se produjo un error durante la instalación del mapa"
},
"no-duplicates-maps": {
"title": "Sin duplicados",
"msg": "No se eliminó ninguna carta"
},
"duplicates-maps-deleted": {
"title": "Duplicados eliminados",
"msg": "Se eliminaron los duplicados"
}
},
"playlists": {
Expand Down Expand Up @@ -690,6 +699,11 @@
"title": "Mantener los mapas creará una copia de los mapas compartidos para la versión actual. De lo contrario, no se mantendrá ningún mapa para esta versión."
},
"valid-btn": "Desvincular mapas"
},
"delete-duplicate-maps": {
"title": "¿Borrar mapas?",
"desc": "Solo el mapa \"{map}\" está duplicado. ¿Estás seguro de que quieres eliminarlo?",
"desc-plural": "Se han encontrado {nb} mapas duplicados. ¿Estás seguro de que quieres eliminarlos?"
}
},
"download-maps": {
Expand Down
16 changes: 15 additions & 1 deletion assets/jsons/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"filters-btn": "Filtres",
"dropdown": {
"export-maps": "Exporter les maps",
"delete-maps": "Supprimer les maps"
"delete-maps": "Supprimer les maps",
"delete-duplicate-maps": "Supprimer les doublons"
}
},
"tabs": {
Expand Down Expand Up @@ -496,6 +497,14 @@
"one-click-install": {
"success": "Installation de la map terminée",
"error": "Une erreur s'est produite lors de l'installation de la map"
},
"no-duplicates-maps": {
"title": "Pas de doublons",
"msg": "Aucune carte n'a été supprimée"
},
"duplicates-maps-deleted": {
"title": "Doublons supprimés",
"msg": "Les doublons ont été supprimés"
}
},
"playlists": {
Expand Down Expand Up @@ -691,6 +700,11 @@
"title": "Conserver les maps créera une copie des maps partagées pour la version actuelle. Dans le cas contraire, aucune map ne sera conservée pour cette version."
},
"valid-btn": "Délier les maps"
},
"delete-duplicate-maps": {
"title": "Supprimer les maps ?",
"desc": "Seule la map \"{map}\" est en double. Es-tu sûr de vouloir la supprimer ?",
"desc-plural": "{nb} maps en double ont été trouvées. Es-tu sûr de vouloir les supprimer ?"
}
},
"download-maps": {
Expand Down
16 changes: 15 additions & 1 deletion assets/jsons/translations/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"filters-btn": "絞り込み",
"dropdown": {
"export-maps": "マップをエクスポート",
"delete-maps": "マップを削除"
"delete-maps": "マップを削除",
"delete-duplicate-maps": " 重複を削除"
}
},
"tabs": {
Expand Down Expand Up @@ -496,6 +497,14 @@
"one-click-install": {
"success": "マップのインストール完了",
"error": "マップのインストール中にエラーが発生しました"
},
"no-duplicates-maps": {
"title": "重複なし",
"msg": "マップは削除されませんでした"
},
"duplicates-maps-deleted": {
"title": "重複削除",
"msg": "重複が削除されました"
}
},
"playlists": {
Expand Down Expand Up @@ -690,6 +699,11 @@
"title": "マップを保持は、リンクを解除した後、共有フォルダから現在のバージョンにすべてのマップをコピーします。これを無効をしても共有マップは失われません。"
},
"valid-btn": "マップのリンクを解除"
},
"delete-duplicate-maps": {
"title": "マップを削除しますか?",
"desc": "マップ「{map}」のみが重複しています。削除してもよろしいですか?",
"desc-plural": "{nb}個の重複したマップが見つかりました。削除してもよろしいですか?"
}
},
"download-maps": {
Expand Down
16 changes: 15 additions & 1 deletion assets/jsons/translations/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"filters-btn": "Фильтр",
"dropdown": {
"export-maps": "Экспорт карт",
"delete-maps": "Удалить карты"
"delete-maps": "Удалить карты",
"delete-duplicate-maps": "Удалить дубликаты"
}
},
"tabs": {
Expand Down Expand Up @@ -496,6 +497,14 @@
"one-click-install": {
"success": "Карта установлена",
"error": "Ошибка установки карты"
},
"no-duplicates-maps": {
"title": "Нет дубликатов",
"msg": "Ни одна карта не была удалена"
},
"duplicates-maps-deleted": {
"title": "Дубликаты удалены",
"msg": "Дубликаты были удалены"
}
},
"playlists": {
Expand Down Expand Up @@ -690,6 +699,11 @@
"title": "Общие карты будут скопированы в папку карт этой версии. Карты не будут потеряны, если это не выбрано."
},
"valid-btn": "Отвязать карты"
},
"delete-duplicate-maps": {
"title": "Удалить карту?",
"desc": "Только карта \"{map}\" является дубликатом. Вы уверены, что хотите ее удалить?",
"desc-plural": "Найдено {nb} дубликатов карт. Вы уверены, что хотите их удалить?"
}
},
"download-maps": {
Expand Down
16 changes: 15 additions & 1 deletion assets/jsons/translations/zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"filters-btn": "篩選",
"dropdown": {
"export-maps": "導出譜面",
"delete-maps": "刪除譜面"
"delete-maps": "刪除譜面",
"delete-duplicate-maps": "刪除重複項"
}
},
"tabs": {
Expand Down Expand Up @@ -496,6 +497,14 @@
"one-click-install": {
"success": "譜面安裝完成",
"error": "安裝譜面時發生錯誤"
},
"no-duplicates-maps": {
"title": "沒有重複",
"msg": "沒有刪除地圖"
},
"duplicates-maps-deleted": {
"title": "重複已刪除",
"msg": "重複已刪除"
}
},
"playlists": {
Expand Down Expand Up @@ -690,6 +699,11 @@
"title": "保留譜面將會在取消關聯後把共享文件夾的所有譜面複製到當前版本。如果此項被禁用,譜面也不會遺失。"
},
"valid-btn": "取消關聯譜面"
},
"delete-duplicate-maps": {
"title": "刪除地圖",
"desc": "只有地圖「{map}」是重複的。你確定要刪除它嗎?",
"desc-plural": "發現了 {nb} 個重複的地圖。你確定要刪除它們嗎?"
}
},
"download-maps": {
Expand Down
16 changes: 15 additions & 1 deletion assets/jsons/translations/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"filters-btn": "筛选",
"dropdown": {
"export-maps": "导出谱面",
"delete-maps": "删除谱面"
"delete-maps": "删除谱面",
"delete-duplicate-maps": "删除重复项"
}
},
"tabs": {
Expand Down Expand Up @@ -496,6 +497,14 @@
"one-click-install": {
"success": "谱面安装完成",
"error": "安装谱面时发生错误"
},
"no-duplicates-maps": {
"title": "没有重复",
"msg": "没有删除地图"
},
"duplicates-maps-deleted": {
"title": "重复已删除",
"msg": "重复已删除"
}
},
"playlists": {
Expand Down Expand Up @@ -690,6 +699,11 @@
"title": "保留谱面将会在取消关联后把共享文件夹的所有谱面复制到当前版本。如果此项被禁用,谱面也不会丢失。"
},
"valid-btn": "取消关联谱面"
},
"delete-duplicate-maps": {
"title": "删除地图",
"desc": "只有地图 \"{map}\" 是重复的。你确定要删除它吗?",
"desc-plural": "发现了 {nb} 个重复的地图。你确定要删除它们吗?"
}
},
"download-maps": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createContext, useRef, useState } from "react";
import { BSVersion } from "shared/bs-version.interface";
import { LocalMapsListPanel } from "./maps/local-maps-list-panel.component";
import { LocalMapsListPanel, LocalMapsListPanelRef } from "./maps/local-maps-list-panel.component";
import { BsmDropdownButton, DropDownItem } from "../shared/bsm-dropdown-button.component";
import { FilterPanel } from "./maps/filter-panel.component";
import { MapFilter } from "shared/models/maps/beat-saver.model";
Expand Down Expand Up @@ -56,7 +56,7 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) {
setPlaylists: playlists$.next.bind(playlists$),
}));

const mapsRef = useRef<any>();
const mapsRef = useRef<LocalMapsListPanelRef>();
const playlistsRef = useRef<LocalPlaylistsListRef>();

const [mapFilter, setMapFilter] = useState<MapFilter>({});
Expand Down Expand Up @@ -106,6 +106,7 @@ export function MapsPlaylistsPanel({ version, isActive }: Props) {
return [
{ icon: "export", text: "pages.version-viewer.maps.search-bar.dropdown.export-maps", onClick: () => mapsRef.current.exportMaps?.() },
{ icon: "trash", text: "pages.version-viewer.maps.search-bar.dropdown.delete-maps", onClick: () => mapsRef.current.deleteMaps?.() },
{ icon: "clean", text: "pages.version-viewer.maps.search-bar.dropdown.delete-duplicate-maps", onClick: () => mapsRef.current.removeDuplicates?.() },
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { MapsManagerService } from "renderer/services/maps-manager.service";
import { BSVersion } from "shared/bs-version.interface";
import { forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useState } from "react";
import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface";
import { Subscription, BehaviorSubject } from "rxjs";
import { Subscription, BehaviorSubject, lastValueFrom } from "rxjs";
import { MapFilter } from "shared/models/maps/beat-saver.model";
import { MapsDownloaderService } from "renderer/services/maps-downloader.service";
import { last, tap } from "rxjs/operators";
Expand Down Expand Up @@ -34,7 +34,13 @@ type Props = {
isActive?: boolean;
};

export const LocalMapsListPanel = forwardRef<unknown, Props>(({ version, className, filter, search, linkedState, isActive }, forwardRef) => {
export type LocalMapsListPanelRef = {
deleteMaps: () => void;
exportMaps: () => void;
removeDuplicates: () => void;
}

export const LocalMapsListPanel = forwardRef<LocalMapsListPanelRef, Props>(({ version, className, filter, search, linkedState, isActive }, forwardRef) => {
const mapsManager = useService(MapsManagerService);
const mapsDownloader = useService(MapsDownloaderService);

Expand Down Expand Up @@ -63,6 +69,12 @@ export const LocalMapsListPanel = forwardRef<unknown, Props>(({ version, classNa
},
exportMaps() {
mapsManager.exportMaps(version, selectedMaps);
},
removeDuplicates() {
return lastValueFrom(mapsManager.deleteDuplicateMaps(maps$.value)).then(res => {
if(!res?.current){ return; }
loadMaps();
}).catch(noop);
}
}),[selectedMaps, maps, version]);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { BsmButton } from "renderer/components/shared/bsm-button.component";
import { BsmImage } from "renderer/components/shared/bsm-image.component";
import { useTranslation } from "renderer/hooks/use-translation.hook";
import { ModalComponent, ModalExitCode } from "renderer/services/modale.service";
import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface";
import BeatConflict from "../../../../../assets/images/apngs/beat-conflict.png";
import { useConstant } from "renderer/hooks/use-constant.hook";

export const DeleteDuplicateMapsModal: ModalComponent<void, { maps: BsmLocalMap[] }> = ({ resolver, options: {data : { maps }}}) => {

const t = useTranslation();
const multiple = useConstant(() => maps.length > 1);

return (
<form className="text-gray-800 dark:text-gray-200 max-w-sm">
<h1 className="text-3xl uppercase tracking-wide w-full text-center">{t("modals.maps-actions.delete-duplicate-maps.title")}</h1>
<BsmImage className="mx-auto h-24" image={BeatConflict} />
<p>{
multiple
? t("modals.maps-actions.delete-duplicate-maps.desc-plural", { nb: `${maps.length}` })
: t("modals.maps-actions.delete-duplicate-maps.desc", { map: `${maps.at(0).rawInfo._songName}` })
}</p>
<div className="grid grid-flow-col grid-cols-2 gap-4 mt-4 h-8">
<BsmButton typeColor="cancel" className="rounded-md flex justify-center items-center transition-all" onClick={() => resolver({ exitCode: ModalExitCode.CANCELED })} withBar={false} text="misc.cancel" />
<BsmButton typeColor="primary" className="rounded-md flex justify-center items-center transition-all" onClick={() => resolver({ exitCode: ModalExitCode.COMPLETED })} withBar={false} text="misc.delete" />
</div>
</form>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const BsmDropdownButton = forwardRef(({ className, classNames, buttonColo
{items?.map(
i =>
i && (
<div key={crypto.randomUUID()} onClick={() => i.onClick?.()} className="flex w-full px-3 py-2 hover:backdrop-brightness-150">
<div key={crypto.randomUUID()} onClick={() => { setExpanded(() => false); i.onClick?.()}} className="flex w-full px-3 py-2 hover:backdrop-brightness-150">
{i.icon && <BsmIcon icon={i.icon} className="h-5 w-5 mr-1 text-inherit" />}
<span className="w-max">{t(i.text)}</span>
</div>
Expand Down
Loading
Loading