[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:
@@ -43,6 +43,8 @@
|
|||||||
"main.CriticalErrorHandler.uncaughtException.button.showDetails": "Show Details",
|
"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.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.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": "&Edit",
|
||||||
"main.menus.app.edit.copy": "Copy",
|
"main.menus.app.edit.copy": "Copy",
|
||||||
"main.menus.app.edit.cut": "Cut",
|
"main.menus.app.edit.cut": "Cut",
|
||||||
|
@@ -13,7 +13,6 @@ import {
|
|||||||
QUIT,
|
QUIT,
|
||||||
SHOW_NEW_SERVER_MODAL,
|
SHOW_NEW_SERVER_MODAL,
|
||||||
NOTIFY_MENTION,
|
NOTIFY_MENTION,
|
||||||
GET_DOWNLOAD_LOCATION,
|
|
||||||
SWITCH_TAB,
|
SWITCH_TAB,
|
||||||
CLOSE_TAB,
|
CLOSE_TAB,
|
||||||
OPEN_TAB,
|
OPEN_TAB,
|
||||||
@@ -92,7 +91,6 @@ import {
|
|||||||
handleMentionNotification,
|
handleMentionNotification,
|
||||||
handleOpenAppMenu,
|
handleOpenAppMenu,
|
||||||
handleQuit,
|
handleQuit,
|
||||||
handleSelectDownload,
|
|
||||||
handlePingDomain,
|
handlePingDomain,
|
||||||
} from './intercom';
|
} from './intercom';
|
||||||
import {
|
import {
|
||||||
@@ -290,7 +288,6 @@ function initializeInterCommunicationEventListeners() {
|
|||||||
ipcMain.on(SHOW_EDIT_SERVER_MODAL, handleEditServerModal);
|
ipcMain.on(SHOW_EDIT_SERVER_MODAL, handleEditServerModal);
|
||||||
ipcMain.on(SHOW_REMOVE_SERVER_MODAL, handleRemoveServerModal);
|
ipcMain.on(SHOW_REMOVE_SERVER_MODAL, handleRemoveServerModal);
|
||||||
ipcMain.handle(GET_AVAILABLE_SPELL_CHECKER_LANGUAGES, () => session.defaultSession.availableSpellCheckerLanguages);
|
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_UPDATE_DOWNLOAD, handleStartDownload);
|
||||||
ipcMain.on(START_UPGRADE, handleStartUpgrade);
|
ipcMain.on(START_UPGRADE, handleStartUpgrade);
|
||||||
ipcMain.handle(PING_DOMAIN, handlePingDomain);
|
ipcMain.handle(PING_DOMAIN, handlePingDomain);
|
||||||
|
@@ -1,18 +1,17 @@
|
|||||||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||||
// See LICENSE.txt for license information.
|
// 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 {MattermostTeam} from 'types/config';
|
||||||
import {MentionData} from 'types/notification';
|
import {MentionData} from 'types/notification';
|
||||||
|
|
||||||
import Config from 'common/config';
|
|
||||||
import {Logger} from 'common/log';
|
import {Logger} from 'common/log';
|
||||||
|
import ServerManager from 'common/servers/serverManager';
|
||||||
import {ping} from 'common/utils/requests';
|
import {ping} from 'common/utils/requests';
|
||||||
|
|
||||||
import {displayMention} from 'main/notifications';
|
import {displayMention} from 'main/notifications';
|
||||||
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
import {getLocalPreload, getLocalURLString} from 'main/utils';
|
||||||
import ServerManager from 'common/servers/serverManager';
|
|
||||||
import ModalManager from 'main/views/modalManager';
|
import ModalManager from 'main/views/modalManager';
|
||||||
import MainWindow from 'main/windows/mainWindow';
|
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> {
|
export function handlePingDomain(event: IpcMainInvokeEvent, url: string): Promise<string> {
|
||||||
return Promise.allSettled([
|
return Promise.allSettled([
|
||||||
ping(new URL(`https://${url}`)),
|
ping(new URL(`https://${url}`)),
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs';
|
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 {ProgressInfo, UpdateInfo} from 'electron-updater';
|
||||||
import {DownloadedItem, DownloadItemDoneEventState, DownloadedItems, DownloadItemState, DownloadItemUpdatedEventState} from 'types/downloads';
|
import {DownloadedItem, DownloadItemDoneEventState, DownloadedItems, DownloadItemState, DownloadItemUpdatedEventState} from 'types/downloads';
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
CLOSE_DOWNLOADS_DROPDOWN,
|
CLOSE_DOWNLOADS_DROPDOWN,
|
||||||
CLOSE_DOWNLOADS_DROPDOWN_MENU,
|
CLOSE_DOWNLOADS_DROPDOWN_MENU,
|
||||||
DOWNLOADS_DROPDOWN_FOCUSED,
|
DOWNLOADS_DROPDOWN_FOCUSED,
|
||||||
|
GET_DOWNLOAD_LOCATION,
|
||||||
HIDE_DOWNLOADS_DROPDOWN_BUTTON_BADGE,
|
HIDE_DOWNLOADS_DROPDOWN_BUTTON_BADGE,
|
||||||
NO_UPDATE_AVAILABLE,
|
NO_UPDATE_AVAILABLE,
|
||||||
OPEN_DOWNLOADS_DROPDOWN,
|
OPEN_DOWNLOADS_DROPDOWN,
|
||||||
@@ -89,12 +90,14 @@ export class DownloadsManager extends JsonFileManager<DownloadedItems> {
|
|||||||
return this.hasDownloads();
|
return this.hasDownloads();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.removeHandler(GET_DOWNLOAD_LOCATION);
|
||||||
ipcMain.removeListener(DOWNLOADS_DROPDOWN_FOCUSED, this.clearAutoCloseTimeout);
|
ipcMain.removeListener(DOWNLOADS_DROPDOWN_FOCUSED, this.clearAutoCloseTimeout);
|
||||||
ipcMain.removeListener(UPDATE_AVAILABLE, this.onUpdateAvailable);
|
ipcMain.removeListener(UPDATE_AVAILABLE, this.onUpdateAvailable);
|
||||||
ipcMain.removeListener(UPDATE_DOWNLOADED, this.onUpdateDownloaded);
|
ipcMain.removeListener(UPDATE_DOWNLOADED, this.onUpdateDownloaded);
|
||||||
ipcMain.removeListener(UPDATE_PROGRESS, this.onUpdateProgress);
|
ipcMain.removeListener(UPDATE_PROGRESS, this.onUpdateProgress);
|
||||||
ipcMain.removeListener(NO_UPDATE_AVAILABLE, this.noUpdateAvailable);
|
ipcMain.removeListener(NO_UPDATE_AVAILABLE, this.noUpdateAvailable);
|
||||||
|
|
||||||
|
ipcMain.handle(GET_DOWNLOAD_LOCATION, this.handleSelectDownload);
|
||||||
ipcMain.on(DOWNLOADS_DROPDOWN_FOCUSED, this.clearAutoCloseTimeout);
|
ipcMain.on(DOWNLOADS_DROPDOWN_FOCUSED, this.clearAutoCloseTimeout);
|
||||||
ipcMain.on(UPDATE_AVAILABLE, this.onUpdateAvailable);
|
ipcMain.on(UPDATE_AVAILABLE, this.onUpdateAvailable);
|
||||||
ipcMain.on(UPDATE_DOWNLOADED, this.onUpdateDownloaded);
|
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});
|
this.willDownloadURLs.set(url, {filePath: saveDialogResult.filePath, bookmark: saveDialogResult.bookmark});
|
||||||
} else {
|
} else {
|
||||||
const filename = this.createFilename(item);
|
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});
|
this.willDownloadURLs.set(url, {filePath: savePath});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,6 +378,46 @@ export class DownloadsManager extends JsonFileManager<DownloadedItems> {
|
|||||||
this.saveAll(downloads);
|
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) => {
|
private markFileAsDeleted = (item: DownloadedItem) => {
|
||||||
const fileId = this.getDownloadedFileId(item);
|
const fileId = this.getDownloadedFileId(item);
|
||||||
const file = this.downloads[fileId];
|
const file = this.downloads[fileId];
|
||||||
|
Reference in New Issue
Block a user