Skip to content
Closed
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
39 changes: 39 additions & 0 deletions src/hooks/useAllMaps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useQuery } from '@tanstack/react-query';

import type { Project, SavedMap } from '@/lib/db';
import { getDb } from '@/lib/db';

export const ALL_MAPS_QUERY_KEY = ['maps', 'all'] as const;

export interface SavedMapWithProject extends SavedMap {
/** Origin project name, or `null` if the project no longer exists. */
originProjectName: string | null;
}

/**
* Query every saved map across all projects, sorted by `updatedAt` desc.
* Each map is joined with its origin project name for cross-project display.
*
* Used by the "All projects" view in MapScreen (#16).
*/
export function useAllMaps() {
return useQuery({
queryKey: ALL_MAPS_QUERY_KEY,
queryFn: async (): Promise<SavedMapWithProject[]> => {
const db = getDb();
const [maps, projects] = await Promise.all([
db.maps.toArray(),
db.projects.toArray(),
]);
const projectMap = new Map<string, Project>();
for (const project of projects) {
projectMap.set(project.localId, project);
}
const enriched = maps.map((map) => ({
...map,
originProjectName: projectMap.get(map.projectLocalId)?.name ?? null,
}));
return enriched.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
},
});
}
6 changes: 6 additions & 0 deletions src/hooks/useMaps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';

import { ALL_MAPS_QUERY_KEY } from '@/hooks/useAllMaps';
import type { SavedMap } from '@/lib/db';
import { getDb } from '@/lib/db';
import type { DownloadProgress } from '@/lib/map/smp-download';
Expand Down Expand Up @@ -39,6 +40,7 @@ export function useCreateMap() {
void queryClient.invalidateQueries({
queryKey: mapsQueryKey(map.projectLocalId),
});
void queryClient.invalidateQueries({ queryKey: ALL_MAPS_QUERY_KEY });
},
});
}
Expand All @@ -56,6 +58,7 @@ export function useRenameMap(projectLocalId: string | null) {
queryKey: mapsQueryKey(projectLocalId),
});
void queryClient.invalidateQueries({ queryKey: ['map', mapId] });
void queryClient.invalidateQueries({ queryKey: ALL_MAPS_QUERY_KEY });
},
});
}
Expand Down Expand Up @@ -92,6 +95,7 @@ export function useDeleteMap(projectLocalId: string | null) {
});
void queryClient.invalidateQueries({ queryKey: ['map', mapId] });
void queryClient.invalidateQueries({ queryKey: ['projects'] });
void queryClient.invalidateQueries({ queryKey: ALL_MAPS_QUERY_KEY });
},
});
}
Expand Down Expand Up @@ -143,11 +147,13 @@ export function useDownloadMap() {
queryKey: mapsQueryKey(map.projectLocalId),
});
void queryClient.invalidateQueries({ queryKey: ['map', map.id] });
void queryClient.invalidateQueries({ queryKey: ALL_MAPS_QUERY_KEY });
},
onError: (_error, { map }) => {
void queryClient.invalidateQueries({
queryKey: mapsQueryKey(map.projectLocalId),
});
void queryClient.invalidateQueries({ queryKey: ALL_MAPS_QUERY_KEY });
},
});
}
57 changes: 57 additions & 0 deletions src/i18n/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,27 @@
"map.download.unknownError": {
"defaultMessage": "Unknown error"
},
"map.history.downloaded": {
"defaultMessage": "Downloaded"
},
"map.history.empty": {
"defaultMessage": "No downloads yet"
},
"map.history.retry": {
"defaultMessage": "Retry"
},
"map.history.size": {
"defaultMessage": "Size: {size}"
},
"map.history.statusError": {
"defaultMessage": "Failed"
},
"map.history.statusReady": {
"defaultMessage": "Ready"
},
"map.history.title": {
"defaultMessage": "Download history"
},
"map.nameDialog.cancel": {
"defaultMessage": "Cancel"
},
Expand All @@ -1241,6 +1262,33 @@
"map.nameDialog.title": {
"defaultMessage": "Save map"
},
"map.overlay.clear": {
"defaultMessage": "Clear all overlays"
},
"map.overlay.drop": {
"defaultMessage": "Drop a .geojson file to show it as a reference layer"
},
"map.overlay.dropActive": {
"defaultMessage": "Drop the file to add the overlay"
},
"map.overlay.empty": {
"defaultMessage": "No reference layers added"
},
"map.overlay.invalid": {
"defaultMessage": "Could not read “{name}”. Not valid GeoJSON."
},
"map.overlay.remove": {
"defaultMessage": "Remove overlay"
},
"map.overlay.title": {
"defaultMessage": "Reference layers"
},
"map.overlay.toggle": {
"defaultMessage": "Toggle overlay visibility"
},
"map.overlay.tooLarge": {
"defaultMessage": "“{name}” is {size}. Large files may slow down the editor."
},
"map.saved.activeError": {
"defaultMessage": "Could not update active map. Please try again."
},
Expand Down Expand Up @@ -1274,6 +1322,9 @@
"map.saved.noProjectLink": {
"defaultMessage": "Go to Home"
},
"map.saved.originProject": {
"defaultMessage": "Origin project"
},
"map.saved.removeActive": {
"defaultMessage": "Remove active"
},
Expand Down Expand Up @@ -1319,6 +1370,12 @@
"map.saved.untitledProject": {
"defaultMessage": "Untitled Project"
},
"map.scope.allProjects": {
"defaultMessage": "All projects"
},
"map.scope.thisProject": {
"defaultMessage": "This project"
},
"map.stylePicker.customMode": {
"defaultMessage": "Custom URL"
},
Expand Down
19 changes: 19 additions & 0 deletions src/i18n/messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,13 @@
"map.download.storageWarning": "Espacio de almacenamiento insuficiente. {available} disponibles, {estimated} estimados.",
"map.download.tryAnyway": "Intentar de todos modos",
"map.download.unknownError": "Error desconocido",
"map.history.downloaded": "Descargado",
"map.history.empty": "Aún no hay descargas",
"map.history.retry": "Reintentar",
"map.history.size": "Tamaño: {size}",
"map.history.statusError": "Fallido",
"map.history.statusReady": "Listo",
"map.history.title": "Historial de descargas",
"map.nameDialog.cancel": "Cancelar",
"map.nameDialog.description": "Guarde esta configuración de mapa como borrador. Luego puede descargarlo como un archivo .smp.",
"map.nameDialog.nameLabel": "Nombre del mapa",
Expand All @@ -382,6 +389,15 @@
"map.nameDialog.saveDraft": "Guardar borrador",
"map.nameDialog.saveError": "No se pudo guardar el mapa. Inténtelo de nuevo.",
"map.nameDialog.title": "Guardar mapa",
"map.overlay.clear": "Limpiar todas las capas",
"map.overlay.drop": "Suelte un archivo .geojson para mostrarlo como capa de referencia",
"map.overlay.dropActive": "Suelte el archivo para añadir la capa",
"map.overlay.empty": "No hay capas de referencia añadidas",
"map.overlay.invalid": "No se pudo leer “{name}”. GeoJSON no válido.",
"map.overlay.remove": "Quitar capa",
"map.overlay.title": "Capas de referencia",
"map.overlay.tooLarge": "“{name}” es {size}. Los archivos grandes pueden ralentizar el editor.",
"map.overlay.toggle": "Alternar visibilidad de la capa",
"map.saved.activeError": "No se pudo actualizar el mapa activo. Inténtelo de nuevo.",
"map.saved.canvasAria": "Lienzo de autoría de mapa",
"map.saved.closeSettings": "Cerrar configuración del mapa",
Expand All @@ -393,6 +409,7 @@
"map.saved.empty": "Aún no hay mapas guardados",
"map.saved.noProject": "Seleccione un proyecto desde Inicio para crear mapas",
"map.saved.noProjectLink": "Ir a Inicio",
"map.saved.originProject": "Proyecto de origen",
"map.saved.removeActive": "Quitar activo",
"map.saved.rename": "Renombrar",
"map.saved.renameDialog.description": "Ingrese un nuevo nombre para este mapa guardado.",
Expand All @@ -408,6 +425,8 @@
"map.saved.statusReady": "Listo",
"map.saved.title": "Mapas guardados",
"map.saved.untitledProject": "Proyecto sin título",
"map.scope.allProjects": "Todos los proyectos",
"map.scope.thisProject": "Este proyecto",
"map.stylePicker.customMode": "URL personalizada",
"map.stylePicker.customUrlHostnameWarning": "Este proveedor de teselas puede no estar disponible para descargas offline. Solo los proveedores compatibles funcionan con la generación de paquetes de mapas.",
"map.stylePicker.customUrlLabel": "URL personalizada",
Expand Down
19 changes: 19 additions & 0 deletions src/i18n/messages/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,13 @@
"map.download.storageWarning": "Espaço de armazenamento insuficiente. {available} disponível, {estimated} estimado.",
"map.download.tryAnyway": "Tentar mesmo assim",
"map.download.unknownError": "Erro desconhecido",
"map.history.downloaded": "Baixado",
"map.history.empty": "Ainda não há downloads",
"map.history.retry": "Tentar novamente",
"map.history.size": "Tamanho: {size}",
"map.history.statusError": "Falhou",
"map.history.statusReady": "Pronto",
"map.history.title": "Histórico de downloads",
"map.nameDialog.cancel": "Cancelar",
"map.nameDialog.description": "Salve esta configuração de mapa como rascunho. Depois você pode baixá-lo como um arquivo .smp.",
"map.nameDialog.nameLabel": "Nome do mapa",
Expand All @@ -382,6 +389,15 @@
"map.nameDialog.saveDraft": "Salvar rascunho",
"map.nameDialog.saveError": "Não foi possível salvar o mapa. Tente novamente.",
"map.nameDialog.title": "Salvar mapa",
"map.overlay.clear": "Limpar todas as camadas",
"map.overlay.drop": "Solte um arquivo .geojson para mostrá-lo como camada de referência",
"map.overlay.dropActive": "Solte o arquivo para adicionar a camada",
"map.overlay.empty": "Nenhuma camada de referência adicionada",
"map.overlay.invalid": "Não foi possível ler “{name}”. GeoJSON inválido.",
"map.overlay.remove": "Remover camada",
"map.overlay.title": "Camadas de referência",
"map.overlay.tooLarge": "“{name}” tem {size}. Arquivos grandes podem lentear o editor.",
"map.overlay.toggle": "Alternar visibilidade da camada",
"map.saved.activeError": "Não foi possível atualizar o mapa ativo. Tente novamente.",
"map.saved.canvasAria": "Tela de autoria de mapa",
"map.saved.closeSettings": "Fechar configurações do mapa",
Expand All @@ -393,6 +409,7 @@
"map.saved.empty": "Ainda não há mapas salvos",
"map.saved.noProject": "Selecione um projeto no Início para criar mapas",
"map.saved.noProjectLink": "Ir para o Início",
"map.saved.originProject": "Projeto de origem",
"map.saved.removeActive": "Remover ativo",
"map.saved.rename": "Renomear",
"map.saved.renameDialog.description": "Insira um novo nome para este mapa salvo.",
Expand All @@ -408,6 +425,8 @@
"map.saved.statusReady": "Pronto",
"map.saved.title": "Mapas salvos",
"map.saved.untitledProject": "Projeto sem título",
"map.scope.allProjects": "Todos os projetos",
"map.scope.thisProject": "Este projeto",
"map.stylePicker.customMode": "URL personalizada",
"map.stylePicker.customUrlHostnameWarning": "Este provedor de mosaicos pode não estar disponível para downloads offline. Somente provedores compatíveis funcionam com a geração de pacotes de mapas.",
"map.stylePicker.customUrlLabel": "URL personalizada",
Expand Down
Loading
Loading