[MM-52139] Force user to reset default downloads directory when the app is not allowed to access it (#2699)

* [MM-52139] Force user to reset default downloads directory when the app is not allowed to access it

* Fix a bug where a different download location choice would cause a problem

* Missed i18n
This commit is contained in:
Devin Binnie
2023-05-02 14:37:14 -04:00
committed by GitHub
parent 09fe196bc6
commit f3a4417464
4 changed files with 50 additions and 19 deletions

View File

@@ -43,6 +43,8 @@
"main.CriticalErrorHandler.uncaughtException.button.showDetails": "Show Details",
"main.CriticalErrorHandler.uncaughtException.dialog.message": "The {appName} app quit unexpectedly. Click \"{showDetails}\" to learn more or \"{reopen}\" to open the application again.\n\nInternal error: {err}",
"main.CriticalErrorHandler.unresponsive.dialog.message": "The window is no longer responsive.\nDo you want to wait until the window becomes responsive again?",
"main.downloadsManager.resetDownloadsFolder": "Please reset the folder where files will download",
"main.downloadsManager.specifyDownloadsFolder": "Specify the folder where files will download",
"main.menus.app.edit": "&Edit",
"main.menus.app.edit.copy": "Copy",
"main.menus.app.edit.cut": "Cut",

View File

@@ -13,7 +13,6 @@ import {
QUIT,
SHOW_NEW_SERVER_MODAL,
NOTIFY_MENTION,
GET_DOWNLOAD_LOCATION,
SWITCH_TAB,
CLOSE_TAB,
OPEN_TAB,
@@ -92,7 +91,6 @@ import {
handleMentionNotification,
handleOpenAppMenu,
handleQuit,
handleSelectDownload,
handlePingDomain,
} from './intercom';
import {
@@ -290,7 +288,6 @@ function initializeInterCommunicationEventListeners() {
ipcMain.on(SHOW_EDIT_SERVER_MODAL, handleEditServerModal);
ipcMain.on(SHOW_REMOVE_SERVER_MODAL, handleRemoveServerModal);
ipcMain.handle(GET_AVAILABLE_SPELL_CHECKER_LANGUAGES, () => session.defaultSession.availableSpellCheckerLanguages);
ipcMain.handle(GET_DOWNLOAD_LOCATION, handleSelectDownload);
ipcMain.on(START_UPDATE_DOWNLOAD, handleStartDownload);
ipcMain.on(START_UPGRADE, handleStartUpgrade);
ipcMain.handle(PING_DOMAIN, handlePingDomain);

View File

@@ -1,18 +1,17 @@
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {app, dialog, IpcMainEvent, IpcMainInvokeEvent, Menu} from 'electron';
import {app, IpcMainEvent, IpcMainInvokeEvent, Menu} from 'electron';
import {MattermostTeam} from 'types/config';
import {MentionData} from 'types/notification';
import Config from 'common/config';
import {Logger} from 'common/log';
import ServerManager from 'common/servers/serverManager';
import {ping} from 'common/utils/requests';
import {displayMention} from 'main/notifications';
import {getLocalPreload, getLocalURLString} from 'main/utils';
import ServerManager from 'common/servers/serverManager';
import ModalManager from 'main/views/modalManager';
import MainWindow from 'main/windows/mainWindow';
@@ -130,17 +129,6 @@ export function handleOpenAppMenu() {
});
}
export async function handleSelectDownload(event: IpcMainInvokeEvent, startFrom: string) {
log.debug('handleSelectDownload', startFrom);
const message = 'Specify the folder where files will download';
const result = await dialog.showOpenDialog({defaultPath: startFrom || Config.downloadLocation,
message,
properties:
['openDirectory', 'createDirectory', 'dontAddToRecent', 'promptToCreate']});
return result.filePaths[0];
}
export function handlePingDomain(event: IpcMainInvokeEvent, url: string): Promise<string> {
return Promise.allSettled([
ping(new URL(`https://${url}`)),

View File

@@ -3,7 +3,7 @@
import path from 'path';
import fs from 'fs';
import {DownloadItem, Event, WebContents, FileFilter, ipcMain, dialog, shell, Menu, app} from 'electron';
import {DownloadItem, Event, WebContents, FileFilter, ipcMain, dialog, shell, Menu, app, IpcMainInvokeEvent} from 'electron';
import {ProgressInfo, UpdateInfo} from 'electron-updater';
import {DownloadedItem, DownloadItemDoneEventState, DownloadedItems, DownloadItemState, DownloadItemUpdatedEventState} from 'types/downloads';
@@ -12,6 +12,7 @@ import {
CLOSE_DOWNLOADS_DROPDOWN,
CLOSE_DOWNLOADS_DROPDOWN_MENU,
DOWNLOADS_DROPDOWN_FOCUSED,
GET_DOWNLOAD_LOCATION,
HIDE_DOWNLOADS_DROPDOWN_BUTTON_BADGE,
NO_UPDATE_AVAILABLE,
OPEN_DOWNLOADS_DROPDOWN,
@@ -89,12 +90,14 @@ export class DownloadsManager extends JsonFileManager<DownloadedItems> {
return this.hasDownloads();
});
ipcMain.removeHandler(GET_DOWNLOAD_LOCATION);
ipcMain.removeListener(DOWNLOADS_DROPDOWN_FOCUSED, this.clearAutoCloseTimeout);
ipcMain.removeListener(UPDATE_AVAILABLE, this.onUpdateAvailable);
ipcMain.removeListener(UPDATE_DOWNLOADED, this.onUpdateDownloaded);
ipcMain.removeListener(UPDATE_PROGRESS, this.onUpdateProgress);
ipcMain.removeListener(NO_UPDATE_AVAILABLE, this.noUpdateAvailable);
ipcMain.handle(GET_DOWNLOAD_LOCATION, this.handleSelectDownload);
ipcMain.on(DOWNLOADS_DROPDOWN_FOCUSED, this.clearAutoCloseTimeout);
ipcMain.on(UPDATE_AVAILABLE, this.onUpdateAvailable);
ipcMain.on(UPDATE_DOWNLOADED, this.onUpdateDownloaded);
@@ -134,7 +137,8 @@ export class DownloadsManager extends JsonFileManager<DownloadedItems> {
this.willDownloadURLs.set(url, {filePath: saveDialogResult.filePath, bookmark: saveDialogResult.bookmark});
} else {
const filename = this.createFilename(item);
const savePath = this.getSavePath(`${Config.downloadLocation}`, filename);
const downloadLocation = await this.verifyMacAppStoreDownloadFolder(filename);
const savePath = this.getSavePath(`${downloadLocation}`, filename);
this.willDownloadURLs.set(url, {filePath: savePath});
}
@@ -374,6 +378,46 @@ export class DownloadsManager extends JsonFileManager<DownloadedItems> {
this.saveAll(downloads);
};
private handleSelectDownload = (event: IpcMainInvokeEvent, startFrom: string) => {
return this.selectDefaultDownloadDirectory(
startFrom,
localizeMessage('main.downloadsManager.specifyDownloadsFolder', 'Specify the folder where files will download'),
);
}
private selectDefaultDownloadDirectory = async (startFrom: string, message: string) => {
log.debug('handleSelectDownload', startFrom);
const result = await dialog.showOpenDialog({defaultPath: startFrom || Config.downloadLocation,
message,
properties:
['openDirectory', 'createDirectory', 'dontAddToRecent', 'promptToCreate']});
return result.filePaths[0];
}
private verifyMacAppStoreDownloadFolder = async (fileName: string) => {
let downloadLocation = Config.downloadLocation;
// eslint-disable-next-line no-undef
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
if (__IS_MAC_APP_STORE__ && downloadLocation) {
try {
const savePath = this.getSavePath(downloadLocation, fileName);
fs.writeFileSync(savePath, '');
fs.unlinkSync(savePath);
} catch (e) {
downloadLocation = await this.selectDefaultDownloadDirectory(
downloadLocation,
localizeMessage('main.downloadsManager.resetDownloadsFolder', 'Please reset the folder where files will download'),
);
Config.set('downloadLocation', downloadLocation);
}
}
return downloadLocation;
}
private markFileAsDeleted = (item: DownloadedItem) => {
const fileId = this.getDownloadedFileId(item);
const file = this.downloads[fileId];