Skip to content
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
4 changes: 4 additions & 0 deletions DistFiles/localization/en/Bloom.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -5138,6 +5138,10 @@ Do you want to go ahead?</note>
<note>ID: ReportProblemDialog.WhatDoing</note>
<note>This is the label for the text field where the user enters what they were doing at the time of the problem.</note>
</trans-unit>
<trans-unit id="ReportProblemDialog.SearchOnline" translate="no">
<source xml:lang="en">Search online</source>
<note>ID: ReportProblemDialog.SearchOnline</note>
</trans-unit>
<trans-unit id="SamplePrintNotification.IGetIt">
<source xml:lang="en">I get it. Do not show this again.</source>
<note>ID: SamplePrintNotification.IGetIt</note>
Expand Down
9 changes: 9 additions & 0 deletions DistFiles/localization/en/BloomLowPriority.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,15 @@
<source xml:lang="en">Bloom was not able to access a microphone.</source>
<note>ID: EditTab.Toolbox.TalkingBookTool.MicrophoneAccessProblem</note>
</trans-unit>
<trans-unit id="ReportProblemDialog.OneDriveProblem" translate="no">
<source xml:lang="en">OneDrive Problem</source>
<note>ID: ReportProblemDialog.OneDriveProblem</note>
<note>The title of a dialog telling the user about a problem with their Microsoft OneDrive.</note>
</trans-unit>
<trans-unit id="ReportProblemDialog.OneDriveErrorMessage" translate="no">
<source xml:lang="en">There is a problem with your Microsoft OneDrive which is preventing Bloom from accessing files.</source>
<note>ID: ReportProblemDialog.OneDriveErrorMessage</note>
</trans-unit>
</body>
</file>
</xliff>
73 changes: 53 additions & 20 deletions src/BloomBrowserUI/problemDialog/NotifyDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from "react";
import { css } from "@emotion/react";
import {
Dialog,
DialogActions,
Expand All @@ -14,18 +15,28 @@ import BloomButton from "../react_components/bloomButton";
import { makeTheme, kindParams } from "./theme";
import { useL10n } from "../react_components/l10nHooks";
import { ProblemKind } from "./ProblemDialog";
import { hookupLinkHandler } from "../utils/linkHandler";
import { kBloomBlue, kFormBackground } from "../utils/colorUtils";

export const NotifyDialog: React.FunctionComponent<{
reportLabel?: string | null;
secondaryLabel?: string | null;
message: string | null;
}> = props => {
const theme = makeTheme(ProblemKind.NonFatal);
export interface INotifyDialogProps {
message?: string | null; // The localized message to notify the user about.
reportLabel?: string | null; // The localized text that goes on the Report button. Omit or pass "" to disable Report button.
secondaryLabel?: string | null; // The localized text that goes on the secondary action button. Omit or pass "" to disable the secondary action button.
detailsBoxText?: string | null; // Localized text to go into a grey details box under the message. Omit or pass "" to not show a details box.
titleOverride?: string | null; // If present, wil be used in place of the dialog title defined for this level in themes.ts
titleL10nKeyOverride?: string | null; // The L10nKey for the titleOverride, if present.
themeOverride?: ProblemKind | null; // If present, will be used in place of the dialog theme defined for this level in themes.ts
}

const englishTitle = kindParams[ProblemKind.NonFatal].title;
const titleKey = kindParams[ProblemKind.NonFatal].l10nKey;
export const NotifyDialog: React.FC<INotifyDialogProps> = props => {
const theme = makeTheme(props.themeOverride || ProblemKind.NonFatal);

const englishTitle = props.titleOverride ?? kindParams[ProblemKind.NonFatal].title;
const titleKey = props.titleL10nKeyOverride ?? kindParams[ProblemKind.NonFatal].l10nKey;
const localizedDlgTitle = useL10n(englishTitle, titleKey);

React.useEffect(() => hookupLinkHandler(), []);

const getDialog = () => {
return (
<Dialog
Expand All @@ -36,6 +47,10 @@ export const NotifyDialog: React.FunctionComponent<{
maxWidth={"md"}
fullScreen={true}
onClose={() => post("common/closeReactDialog")}
css={css`
a {
color: ${kBloomBlue};
}`}
>
<DialogTitle className={"dialog-title allowSelect"}>
<Typography variant="h6">{localizedDlgTitle}</Typography>
Expand All @@ -45,16 +60,29 @@ export const NotifyDialog: React.FunctionComponent<{
onClick={() => post("common/closeReactDialog")}
/> */}
</DialogTitle>
<DialogContent className={"dialog-content"}>
{/* InnerHTML is used so that we can insert markup like <br> into the message. */}
<DialogContentText
className="allowSelect"
dangerouslySetInnerHTML={{
__html: props.message || ""
}}
/>
</DialogContent>
{getDialogActionButtons()}
<DialogContent className={"dialog-content"}>
{/* InnerHTML is used so that we can insert markup like <br> into the message. */}
<DialogContentText
className="allowSelect"
dangerouslySetInnerHTML={{
__html: props.message || ""
}}
/>
{props.detailsBoxText &&
<DialogContentText
css={css`
background-color: ${kFormBackground};
padding: 10px;
margin-top: 20px;
margin-bottom: 20px;
}`}
dangerouslySetInnerHTML={{
__html: props.detailsBoxText || ""
}}
/>
}
</DialogContent>
{getDialogActionButtons()}
</Dialog>
);
};
Expand Down Expand Up @@ -111,16 +139,21 @@ export const NotifyDialog: React.FunctionComponent<{
};

const getCloseButton = (): JSX.Element | null => {
const buttonLabel = props.themeOverride === ProblemKind.Fatal ? "Quit" : "Close";
const l10nKey =
props.themeOverride === ProblemKind.Fatal
? "ReportProblemDialog.Quit"
: "Common.Close";
return (
<BloomButton
enabled={true}
l10nKey={"Common.Close"}
l10nKey={l10nKey}
hasText={true}
onClick={() => {
post("common/closeReactDialog");
}}
>
Close
{buttonLabel}
</BloomButton>
);
};
Expand Down
11 changes: 3 additions & 8 deletions src/BloomBrowserUI/problemDialog/ProblemDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from "react";
import "./ProblemDialog.less";
import { NotifyDialog } from "./NotifyDialog";
import { INotifyDialogProps, NotifyDialog } from "./NotifyDialog";
import { ReportDialog } from "./ReportDialog";
import { WireUpForWinforms } from "../utils/WireUpWinform";

Expand All @@ -9,15 +9,10 @@ export enum ProblemKind {
Notify = "notify",
User = "user",
NonFatal = "nonfatal",
Fatal = "fatal"
Fatal = "fatal",
}

export const ProblemDialog: React.FunctionComponent<{
level: ProblemKind;
message: string; // The localized message to notify the user about.
reportLabel?: string; // The localized text that goes on the Report button. Omit or pass "" to disable Report button.
secondaryLabel?: string; // The localized text that goes on the secondary action button. Omit or pass "" to disable the secondary action button.
}> = props => {
export const ProblemDialog: React.FC<{level:ProblemKind} & Partial<INotifyDialogProps>> = props => {
if (props.level === ProblemKind.Notify) {
return <NotifyDialog {...props} />;
} else {
Expand Down
1 change: 0 additions & 1 deletion src/BloomBrowserUI/problemDialog/ReportDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ export const ReportDialog: React.FunctionComponent<{
includeScreenshot
},
result => {
console.log(JSON.stringify(result.data));
const failureResponseString = "failed:";
const link = result.data.issueLink;
if (link.startsWith(failureResponseString)) {
Expand Down
2 changes: 1 addition & 1 deletion src/BloomBrowserUI/problemDialog/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const kindParams = {
primaryColor: kNonFatalColor,
title: "Bloom had a problem",
l10nKey: "ReportProblemDialog.NonFatalTitle"
}
},
};

export function makeTheme(kind: ProblemKind): Theme {
Expand Down
3 changes: 2 additions & 1 deletion src/BloomBrowserUI/utils/linkHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const handler = (e: Event) => {
if (!href) {
return;
}
if (href.startsWith("http") || href.startsWith("mailto")) {
if (href.startsWith("http") || href.startsWith("mailto") || href.startsWith('file')) {
console.log('handling link ', href);
e.preventDefault();
e.stopPropagation();
postString("link", href);
Expand Down
12 changes: 10 additions & 2 deletions src/BloomExe/Book/BookInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ public static string InstallFreshInstanceGuid(string bookFolder)
/// This method recurses through the folders under 'pathToDirectory' and keeps track of all the unique bookInstanceId
/// guids. When a duplicate is found, we will call InstallFreshInstanceGuid().
/// </summary>
public static void RepairDuplicateInstanceIds(
public static void CheckForDuplicateInstanceIdsAndRepair(
string pathToDirectory,
Func<string, bool> okToChangeId
)
Expand Down Expand Up @@ -1006,7 +1006,15 @@ public static BookMetaData GetRepairedMetaDataWithIdOnly(string metaDataPath)
{
if (RobustFile.Exists(metaDataPath))
{
var id = GetIdFromDamagedMetaDataString(RobustFile.ReadAllText(metaDataPath));
string id;
try
{
id = GetIdFromDamagedMetaDataString(RobustFile.ReadAllText(metaDataPath));
}
catch (IOException error)
{
throw new FileException(metaDataPath, error);
}
if (id != null)
return new BookMetaData() { Id = id };
}
Expand Down
6 changes: 4 additions & 2 deletions src/BloomExe/Collection/CollectionSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Bloom.Book;
using Bloom.MiscUI;
using Bloom.Publish.BloomPub;
using Bloom.Utils;
using Bloom.web.controllers;
using DesktopAnalytics;
using L10NSharp;
Expand Down Expand Up @@ -479,7 +480,7 @@ public void Load()

LoadDictionary(xml, "Palette", ColorPalettes);
}
catch (Exception)
catch (Exception originalError)
{
string settingsContents;
try
Expand All @@ -495,7 +496,8 @@ public void Load()
// We used to notify the user of a problem here.
// But now we decided it is better to catch at a higher level, at OpenProjectWindow(), else we have two different
// error UI dialogs for the same problem. See BL-9916.
throw;

throw new FileException(SettingsFilePath, originalError);
}

try
Expand Down
6 changes: 3 additions & 3 deletions src/BloomExe/CollectionTab/CollectionTabView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -278,19 +278,19 @@ public void ReadyToShowCollections()
// However, until we get rid of the old collection tab, it's tricky to move it, so I've just
// duplicated it here.
// Doing it at this point seems to work fine.
RepairDuplicates();
CheckForDuplicatesAndRepair();
Controls.Add(_reactControl);
}
)
);
}

private void RepairDuplicates()
private void CheckForDuplicatesAndRepair()
{
var collectionPath = _model.TheOneEditableCollection.PathToDirectory;
// A book's ID may not be changed if we have a TC and the book is actually in the shared folder.
// Eventually we may allow it if the book is checked out.
BookInfo.RepairDuplicateInstanceIds(
BookInfo.CheckForDuplicateInstanceIdsAndRepair(
collectionPath,
(bookPath) =>
{
Expand Down
11 changes: 10 additions & 1 deletion src/BloomExe/ErrorReporter/HtmlErrorReporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Bloom.Api;
using Bloom.MiscUI;
using Bloom.ToPalaso;
using Bloom.Utils;
using Bloom.web.controllers;
using SIL.IO;
using SIL.Reporting;
Expand Down Expand Up @@ -217,6 +218,14 @@ private void NotifyUserOfProblemInternal(

try
{
string filePath = FileException.GetFilePathIfPresent(exception);
// FileException is a Bloom exception to capture the filepath. We want to report the inner, original exception.
Exception originalException = FileException.UnwrapIfFileException(exception);
if (OneDriveUtils.CheckForAndHandleOneDriveExceptions(originalException, filePath))
{
return;
}

if (policy == null)
{
policy = new ShowAlwaysPolicy();
Expand All @@ -227,7 +236,7 @@ private void NotifyUserOfProblemInternal(
ShowNotifyDialog(
ProblemLevel.kNotify,
message,
exception,
originalException,
reportButtonLabel,
onReportButtonClicked,
extraButtonLabel,
Expand Down
11 changes: 8 additions & 3 deletions src/BloomExe/MiscUI/StartupScreenManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,14 @@ private static void CloseFastSplashScreen()

public static void CloseSplashScreen()
{
_splashForm?.FadeAndClose(); //it's going to hang around while it fades,
_doWhenSplashScreenShouldClose?.Invoke();
DoLastOfAllAfterClosingSplashScreen?.Invoke();
if (_splashForm == null || !_splashForm.IsDisposed)
{
// We just want to skip the following steps if _splashForm is there but disposed, as this will cause errors.
// They should behave properly if _splashForm is null.
_splashForm?.FadeAndClose(); //it's going to hang around while it fades,
_doWhenSplashScreenShouldClose?.Invoke();
DoLastOfAllAfterClosingSplashScreen?.Invoke();
}

_splashForm = null;
_doWhenSplashScreenShouldClose = null; // Do these actions only once.
Expand Down
21 changes: 19 additions & 2 deletions src/BloomExe/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
using Microsoft.Web.WebView2.Core;
using System.Text;
using Bloom.Utils;
using Bloom.web.controllers;

namespace Bloom
{
Expand Down Expand Up @@ -1297,6 +1298,22 @@ private static void HandleErrorOpeningProjectWindow(Exception error, string proj
_projectContext = null;
}

// FileException is a Bloom exception to capture the filepath. We want to report the inner, original exception.
Exception originalError = FileException.UnwrapIfFileException(error);
string errorFilePath = FileException.GetFilePathIfPresent(error);
Logger.WriteError(
$"*** Error loading collection {Path.GetFileNameWithoutExtension(projectPath)}, on filepath: {errorFilePath}",
originalError
);

// Normally, NotifyUserOfProblem would take an exception and do this special-exception processing for us.
// But in this case, we don't pass the exception to NotifyUserOfProblem because we may subsequently end up
// calling SendReportWithoutUI. Therefore, we must check for the special exception independently.
if (OneDriveUtils.CheckForAndHandleOneDriveExceptions(error))
{
return;
}

ErrorResult reportPressedResult = ErrorResult.Yes;
// NB: I added the email to this directly because, at least on my machine, the old error report dialog had become unworkable
// because, presumably, I haven't set things up properly with gmail.
Expand All @@ -1322,7 +1339,7 @@ private static void HandleErrorOpeningProjectWindow(Exception error, string proj
var additionalPathsToInclude = Directory.GetFiles(dirName);
_applicationContainer.ProblemReportApi.SendReportWithoutUI(
ProblemLevel.kNonFatal,
error,
originalError,
errorMessage,
"",
additionalPathsToInclude
Expand All @@ -1333,7 +1350,7 @@ private static void HandleErrorOpeningProjectWindow(Exception error, string proj
// No email... just fallback to the WinFormsErrorReporter, which will allow the user to email us.
// Unfortunately, we won't be able to automatically get the .bloomCollection file from that.
SIL.Reporting.ErrorReport.ReportNonFatalExceptionWithMessage(
error,
originalError,
errorMessage
);
}
Expand Down
Loading