Skip to content

Commit 53a8a38

Browse files
authored
Merge pull request #1462 from nextcloud/feat/support-files-27
feat: migrate files app integration to new API
2 parents d7d9f26 + ea29e2f commit 53a8a38

File tree

16 files changed

+296
-208
lines changed

16 files changed

+296
-208
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
js/
22
l10n/
33
src/adminSettings.js
4-
src/filetypes.js
54
src/utils.js

css/filetypes.css

Lines changed: 0 additions & 3 deletions
This file was deleted.

lib/Controller/PageController.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,27 @@
1313
namespace OCA\Maps\Controller;
1414

1515
use OCA\Files\Event\LoadSidebar;
16+
use OCA\Maps\Service\MyMapsService;
1617
use OCA\Viewer\Event\LoadViewer;
1718
use OCP\AppFramework\Controller;
19+
use OCP\AppFramework\Http\RedirectResponse;
1820
use OCP\AppFramework\Http\TemplateResponse;
21+
use OCP\AppFramework\Services\IInitialState;
1922
use OCP\EventDispatcher\IEventDispatcher;
2023
use OCP\IConfig;
21-
use OCP\IInitialStateService;
2224
use OCP\IRequest;
25+
use OCP\IURLGenerator;
2326

2427
class PageController extends Controller {
2528

2629
public function __construct(
2730
string $appName,
2831
IRequest $request,
32+
private string $userId,
2933
private IEventDispatcher $eventDispatcher,
3034
private IConfig $config,
31-
private IInitialStateService $initialStateService,
32-
private string $userId,
35+
private IInitialState $initialState,
36+
private IURLGenerator $urlGenerator,
3337
) {
3438
parent::__construct($appName, $request);
3539
}
@@ -50,7 +54,7 @@ public function index(): TemplateResponse {
5054
$this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer());
5155

5256
$params = ['user' => $this->userId];
53-
$this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes');
57+
$this->initialState->provideInitialState('photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes');
5458
$response = new TemplateResponse('maps', 'main', $params);
5559

5660
$this->addCsp($response);
@@ -62,12 +66,21 @@ public function index(): TemplateResponse {
6266
* @NoAdminRequired
6367
* @NoCSRFRequired
6468
*/
65-
public function indexMyMap($myMapId): TemplateResponse {
69+
public function indexMyMap(int $myMapId, MyMapsService $service): TemplateResponse|RedirectResponse {
70+
$map = $service->getMyMap($myMapId, $this->userId);
71+
if ($map !== null && $map['id'] !== $myMapId) {
72+
// Instead of the id of the map containing folder the '.index.maps' file id was passed so redirect
73+
// this happens if coming from the files app integration
74+
return new RedirectResponse(
75+
$this->urlGenerator->linkToRouteAbsolute('maps.page.indexMyMap', ['myMapId' => $map['id']]),
76+
);
77+
}
78+
6679
$this->eventDispatcher->dispatch(LoadSidebar::class, new LoadSidebar());
6780
$this->eventDispatcher->dispatch(LoadViewer::class, new LoadViewer());
6881

6982
$params = ['user' => $this->userId];
70-
$this->initialStateService->provideInitialState($this->appName, 'photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes');
83+
$this->initialState->provideInitialState('photos', $this->config->getAppValue('photos', 'enabled', 'no') === 'yes');
7184
$response = new TemplateResponse('maps', 'main', $params);
7285

7386
$this->addCsp($response);

lib/Listener/LoadAdditionalScriptsListener.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ public function handle(Event $event): void {
4040
return;
4141
}
4242

43-
Util::addScript('maps', 'maps-filetypes');
44-
Util::addStyle('maps', 'filetypes');
43+
Util::addInitScript('maps', 'maps-init-files');
4544
}
4645
}

lib/Service/MyMapsService.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,30 @@ public function getAllMyMaps($userId) {
148148
return $MyMaps;
149149
}
150150

151+
/**
152+
* Try to lookup a my map by id
153+
*
154+
* @param int $id The map id to lookup
155+
* @param string $userId The current user id
156+
* @return null|array Either the MyMap or null if not found with that id for the given user
157+
*/
158+
public function getMyMap(int $id, string $userId) {
159+
$userFolder = $this->root->getUserFolder($userId);
160+
$node = $userFolder->getFirstNodeById($id);
161+
if ($node instanceof Folder) {
162+
try {
163+
$node = $node->get('.index.maps');
164+
} catch (NotFoundException) {
165+
return null;
166+
}
167+
}
168+
169+
if ($node->getMimetype() === 'application/x-nextcloud-maps') {
170+
return $this->node2MyMap($node, $userFolder);
171+
}
172+
return null;
173+
}
174+
151175
public function updateMyMap($id, $values, $userId) {
152176
$userFolder = $this->root->getUserFolder($userId);
153177
$folders = $userFolder->getById($id);
@@ -158,7 +182,7 @@ public function updateMyMap($id, $values, $userId) {
158182
try {
159183
$file = $folder->get('.index.maps');
160184
} catch (NotFoundException $e) {
161-
$file = $folder->newFile('.index.maps', $content = '{}');
185+
$file = $folder->newFile('.index.maps', '{}');
162186
}
163187
$mapData = json_decode($file->getContent(), true);
164188
$renamed = false;

package-lock.json

Lines changed: 46 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@
3838
"dependencies": {
3939
"@fortawesome/fontawesome-free": "^6.7.2",
4040
"@maplibre/maplibre-gl-leaflet": "^0.1.2",
41+
"@mdi/svg": "^7.4.47",
4142
"@nextcloud/auth": "^2.5.1",
4243
"@nextcloud/axios": "^2.5.1",
4344
"@nextcloud/dialogs": "^6.3.2",
4445
"@nextcloud/event-bus": "^3.3.1",
46+
"@nextcloud/files": "^3.12.0",
4547
"@nextcloud/l10n": "^3.1.0",
4648
"@nextcloud/moment": "^1.3.4",
4749
"@nextcloud/paths": "^2.1.0",
@@ -84,6 +86,8 @@
8486
"@nextcloud/eslint-config": "^8.4.1",
8587
"@nextcloud/stylelint-config": "^3.1.0",
8688
"@nextcloud/webpack-vue-config": "^6.3.0",
87-
"@types/leaflet": "^1.9.20"
89+
"@types/leaflet": "^1.9.20",
90+
"@vue/tsconfig": "^0.5.1",
91+
"typescript": "^5.9.2"
8892
}
8993
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import axios from '@nextcloud/axios'
2+
import { showError, showSuccess } from '@nextcloud/dialogs'
3+
import { FileAction, Permission } from '@nextcloud/files'
4+
import { n, t } from '@nextcloud/l10n'
5+
import { generateUrl } from '@nextcloud/router'
6+
7+
import svgMapMarker from '@mdi/svg/svg/map-marker.svg?raw'
8+
9+
export default new FileAction({
10+
id: 'maps:import-device',
11+
12+
displayName() {
13+
return t('maps', 'Import as devices in Maps')
14+
},
15+
16+
enabled(files) {
17+
if (files.length !== 1) {
18+
return false
19+
}
20+
21+
const [file] = files
22+
if (!(file.permissions & Permission.READ)) {
23+
return false
24+
}
25+
return [
26+
'application/gpx+xml',
27+
'application/vnd.google-earth.kmz',
28+
'application/vnd.google-earth.kml+xml',
29+
].includes(file.mime)
30+
},
31+
32+
async exec(file) {
33+
const path = file.path
34+
const url = generateUrl('/apps/maps/import/devices')
35+
try {
36+
const { data } = await axios.post(url, { path })
37+
const number = typeof data === 'number' ? data : data.nbImported
38+
showSuccess(n('maps', 'One device imported', '%n devices imported', number))
39+
} catch (error) {
40+
showError(t('maps', 'Failed to import devices'))
41+
console.error('Failed to import devices', { error })
42+
}
43+
return null
44+
},
45+
46+
iconSvgInline() {
47+
return svgMapMarker
48+
},
49+
})
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import axios from '@nextcloud/axios'
2+
import { showError, showSuccess } from '@nextcloud/dialogs'
3+
import { FileAction, Permission } from '@nextcloud/files'
4+
import { n, t } from '@nextcloud/l10n'
5+
import { generateUrl } from '@nextcloud/router'
6+
7+
import svgMapMarker from '@mdi/svg/svg/map-marker.svg?raw'
8+
9+
export default new FileAction({
10+
id: 'maps:import-as-favorite',
11+
12+
displayName() {
13+
return t('maps', 'Import as favorites in Maps')
14+
},
15+
16+
enabled(files) {
17+
if (files.length !== 1) {
18+
return false
19+
}
20+
21+
const [file] = files
22+
if (!(file.permissions & Permission.READ)) {
23+
return false
24+
}
25+
return [
26+
'application/geo+json',
27+
'application/gpx+xml',
28+
'application/vnd.google-earth.kmz',
29+
'application/vnd.google-earth.kml+xml',
30+
].includes(file.mime)
31+
},
32+
33+
async exec(file) {
34+
const path = file.path
35+
const url = generateUrl('/apps/maps/import/favorites')
36+
try {
37+
const { data } = await axios.post(url, { path })
38+
const number = typeof data === 'number' ? data : data.nbImported
39+
showSuccess(n('maps', 'One favorite imported', '%n favorites imported', number))
40+
} catch (error) {
41+
showError(t('maps', 'Failed to import favorites'))
42+
console.error('Failed to import favorites', { error })
43+
}
44+
return null
45+
},
46+
47+
iconSvgInline() {
48+
return svgMapMarker
49+
},
50+
})

0 commit comments

Comments
 (0)