diff --git a/src/assets/new-project/assets/css/style.css b/src/assets/new-project/assets/css/style.css index b1a94ca10b..6379f5f285 100644 --- a/src/assets/new-project/assets/css/style.css +++ b/src/assets/new-project/assets/css/style.css @@ -1120,7 +1120,7 @@ img { top: 0; left: 0; background: #fd7e14; - color: white; + color: black; padding: 5px; border-radius: 4px; opacity: 0; diff --git a/src/extensions/default/Git/src/Panel.js b/src/extensions/default/Git/src/Panel.js index d62ddf1560..b183ceacfe 100644 --- a/src/extensions/default/Git/src/Panel.js +++ b/src/extensions/default/Git/src/Panel.js @@ -20,6 +20,7 @@ define(function (require, exports) { StringUtils = brackets.getModule("utils/StringUtils"), Strings = brackets.getModule("strings"), Metrics = brackets.getModule("utils/Metrics"), + NotificationUI = brackets.getModule("widgets/NotificationUI"), Constants = require("src/Constants"), Git = require("src/git/Git"), Events = require("./Events"), @@ -1386,6 +1387,15 @@ define(function (require, exports) { if(!StateManager.get(GIT_PANEL_SHOWN_ON_FIRST_BOOT)){ StateManager.set(GIT_PANEL_SHOWN_ON_FIRST_BOOT, true); toggle(true); + NotificationUI.createFromTemplate( + Strings.GIT_TOAST_TITLE, + Strings.GIT_TOAST_MESSAGE, + "git-toolbar-icon", { + allowedPlacements: ['left'], + dismissOnClick: true, + toastStyle: "width-250" + } + ); } // Add info from Git to panel Git.getConfig("user.name").then(function (currentUserName) { diff --git a/src/extensionsIntegrated/Phoenix/guided-tour.js b/src/extensionsIntegrated/Phoenix/guided-tour.js index 681397785f..5cef4901ea 100644 --- a/src/extensionsIntegrated/Phoenix/guided-tour.js +++ b/src/extensionsIntegrated/Phoenix/guided-tour.js @@ -84,7 +84,7 @@ define(function (require, exports, module) { userAlreadyDidAction.beautifyCodeShown = true; PhStore.setItem(GUIDED_TOUR_LOCAL_STORAGE_KEY, JSON.stringify(userAlreadyDidAction)); Metrics.countEvent(Metrics.EVENT_TYPE.UI, "guide", "beautify"); - currentlyShowingNotification = NotificationUI.createFromTemplate( + currentlyShowingNotification = NotificationUI.createFromTemplate( Strings.CMD_BEAUTIFY_CODE, StringUtils.format(Strings.BEAUTIFY_CODE_NOTIFICATION, keyboardShortcut), "editor-context-menu-edit.beautifyCode", { allowedPlacements: ['left', 'right'], @@ -113,7 +113,8 @@ define(function (require, exports, module) { userAlreadyDidAction.newProjectShown = true; PhStore.setItem(GUIDED_TOUR_LOCAL_STORAGE_KEY, JSON.stringify(userAlreadyDidAction)); Metrics.countEvent(Metrics.EVENT_TYPE.UI, "guide", "newProj"); - currentlyShowingNotification = NotificationUI.createFromTemplate(Strings.NEW_PROJECT_NOTIFICATION, + currentlyShowingNotification = NotificationUI.createFromTemplate( + Strings.START_PROJECT, Strings.NEW_PROJECT_NOTIFICATION, "newProject", { allowedPlacements: ['top', 'bottom'], autoCloseTimeS: 15, diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index ba17a00152..bebda033fd 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -878,7 +878,7 @@ define({ "HEALTH_DATA_NOTIFICATION": "Health Report Preferences", "HEALTH_FIRST_POPUP_TITLE": "Privacy Notice", "HEALTH_DATA_DO_TRACK": "Share anonymous information on how I use {APP_NAME}", - "HEALTH_DATA_NOTIFICATION_MESSAGE": "{APP_NAME} does not collect or process any personally identifiable information, but collects anonymous usage statistics to guard your privacy. Anonymous data is exempt from GDPR/CCPA notification requirements, but we believe you need to have a choice to opt out of anonymous data collection as well.

You can see your data or choose not to share any anonymous data by selecting Help > Health Report. These anonymous app usage statistics and error reports helps prioritize features, find bugs, and spot usability issues for improving your experience with {APP_NAME}. Without this data, we would not know what features it is worth building for you!

", + "HEALTH_DATA_NOTIFICATION_MESSAGE": "{APP_NAME} does not collect or process any personally identifiable information, but collects anonymous usage statistics to guard your privacy. Anonymous data is exempt from GDPR/CCPA notification requirements, but we believe you need to have a choice to opt out of anonymous data collection as well.

You can see your data or choose not to share any anonymous data by selecting Help > Health Report. These anonymous app usage statistics and error reports helps prioritize features, find bugs, and spot usability issues for improving your experience with {APP_NAME}. Without this data, we would not know what features it is worth building for you!
", "HEALTH_DATA_PREVIEW": "{APP_NAME} Health Report", "HEALTH_DATA_PREVIEW_INTRO": "

{APP_NAME} does not collect or process any personally identifiable information, but collects anonymous usage statistics to guard your privacy. These anonymous app usage statistics and error reports helps prioritize features, find bugs, and spot usability issues for improving your experience with {APP_NAME}.

Below is a preview of the data that will be sent in your next Health Report if it is enabled. (Also see developer console for error logs marked 'Caught Critical error'.)

", @@ -1218,9 +1218,9 @@ define({ "PREVIEW": "Preview", "BUILD_WEBSITE": "Build Website", "VIEW_MORE": "View More...", - "NEW_PROJECT_NOTIFICATION": "Click this icon to open the `New Project` window again.
See Recent Projects, Open Folder or start projects from templates.

ok", - "BEAUTIFY_CODE_NOTIFICATION": "Click here or press `{0}` to Beautify code.

ok", - "DEFAULT_PROJECT_NOTIFICATION": "Click here to open the
default project in phoenix.
ok", + "NEW_PROJECT_NOTIFICATION": "Click this icon to open the `Start Project` window again.
See Recent Projects, Open Folder or start projects from templates.
", + "BEAUTIFY_CODE_NOTIFICATION": "Click here or press `{0}` to beautify code.
", + "DEFAULT_PROJECT_NOTIFICATION": "Click here to open the
default project in {APP_NAME}.
ok", "DIRECTORY_REPLACE_MESSAGE": "The selected folder {0} is not empty. Are you sure you want to replace the folder contents with the project?", "DEFAULT_PROJECT_HTML_CLICK_HERE": "Click here to locate this <span> in the HTML file", "BUILD_WEBSITE_SECTION": "Build Website", @@ -1529,6 +1529,8 @@ define({ "ERROR_NO_REMOTE_SELECTED": "No remote has been selected for {0}!", "ERROR_BRANCH_LIST": "Getting branch list failed", "ERROR_FETCH_REMOTE": "Fetching remote information failed", + "GIT_TOAST_TITLE": "Explore Git Features in Phoenix Code", + "GIT_TOAST_MESSAGE": "Click the Git panel icon to manage your repository. Easily commit, push, pull, and view your project history—all in one place.
Learn more about the Git panel →", // surveys "SURVEY_TITLE_VOTE_FOR_FEATURES_YOU_WANT": "Vote for the features you want to see next!" diff --git a/src/styles/brackets.less b/src/styles/brackets.less index c8278aeaa4..305036fc59 100644 --- a/src/styles/brackets.less +++ b/src/styles/brackets.less @@ -3215,35 +3215,35 @@ label input { color: black; // text color } -.notification-popup-container.style-danger { +.notification-ui-tooltip.style-danger, .notification-ui-arrow.style-danger, .notification-popup-container.style-danger { background: var(--bc-toast-danger-bg-color); a { color: white; cursor: pointer; } } -.notification-popup-container.style-error { +.notification-ui-tooltip.style-error, .notification-ui-arrow.style-error, .notification-popup-container.style-error { background: var(--bc-toast-error-bg-color); a { color: white; cursor: pointer; } } -.notification-popup-container.style-info { +.notification-ui-tooltip.style-info, .notification-ui-arrow.style-info, .notification-popup-container.style-info { background: var(--bc-toast-info-bg-color); a { color: blue; cursor: pointer; } } -.notification-popup-container.style-success { +.notification-ui-tooltip.style-success, .notification-ui-arrow.style-success, .notification-popup-container.style-success { background: var(--bc-toast-success-bg-color); a { color: darkblue; cursor: pointer; } } -.notification-popup-container.style-warning { +.notification-ui-tooltip.style-warning, .notification-ui-arrow.style-warning, .notification-popup-container.style-warning { background: var(--bc-toast-warning-bg-color); a { color: white; @@ -3273,6 +3273,10 @@ label input { top: 0; right: 8px; cursor: pointer; + color: @notification-text; +} +.notification-popup-close-button.arrow { + top: 8px; } .notification-popup-close-button:hover { color: white; @@ -3281,10 +3285,16 @@ label input { .notification-dialog-title { font-size: 16px; font-weight: bold; + padding-right: 25px; } .notification-dialog-content a { - color: #00ccff; + a { + color: @bc-text-beige; + } + a:hover { + color: @bc-text-alt; + } } .github-stars-button { diff --git a/src/styles/brackets_core_ui_variables.less b/src/styles/brackets_core_ui_variables.less index 6444d4fd57..9326487c3b 100644 --- a/src/styles/brackets_core_ui_variables.less +++ b/src/styles/brackets_core_ui_variables.less @@ -92,6 +92,7 @@ // Text @bc-text: #333; +@bc-text-beige: #F5E6D3; @bc-text-alt: #fff; @bc-text-emphasized: #111; @bc-text-link: #0083e8; @@ -202,6 +203,7 @@ @dark-bc-warning-bg-low: #ffd966; @dark-bc-warning-text: #fff; @dark-bc-warning-text-low: #333333; +@notification-text: #333333; // Text @dark-bc-text: #ccc; diff --git a/src/styles/brackets_patterns_override.less b/src/styles/brackets_patterns_override.less index 9d882ca36a..c28a85668c 100644 --- a/src/styles/brackets_patterns_override.less +++ b/src/styles/brackets_patterns_override.less @@ -95,12 +95,23 @@ a:focus { top: 0; left: 0; background: #fd7e14; - color: white; + color: black; font-weight: bold; - padding: 5px; + padding: 9px 12px 9px 12px; + min-width: 200px; + max-width: 450px; border-radius: 4px; font-size: 90%; opacity: 0; + p { + margin-bottom: 5px; + } + a { + color: @bc-text-beige; + } + a:hover { + color: @bc-text-alt; + } } .notification-ui-hidden { opacity: 0; @@ -112,6 +123,9 @@ a:focus { transition: opacity 0.5s ease; transition-delay:0.2s; } +.width-250 { + width: 250px; +} /* working set drag ghost styles */ .wsv-drag-ghost { diff --git a/src/widgets/NotificationUI.js b/src/widgets/NotificationUI.js index 9fd567aaa5..b7325124e2 100644 --- a/src/widgets/NotificationUI.js +++ b/src/widgets/NotificationUI.js @@ -198,6 +198,7 @@ define(function (require, exports, module) { * }); * ``` * + * @param {string} title The title for the notification. * @param {string|Element} template A string template or HTML Element to use as the dialog HTML. * @param {String} [elementID] optional id string if provided will show the notification pointing to the element. * If no element is specified, it will be managed as a generic notification. @@ -207,19 +208,21 @@ define(function (require, exports, module) { * Values can be a mix of `['top', 'bottom', 'left', 'right']` * * `autoCloseTimeS` - Time in seconds after which the notification should be auto closed. Default is never. * * `dismissOnClick` - when clicked, the notification is closed. Default is true(dismiss). + * * `toastStyle` - To style the toast notification for error, warning, info etc. Can be + * one of `NotificationUI.NOTIFICATION_STYLES_CSS_CLASS.*` or your own css class name. * @return {Notification} Object with a done handler that resolves when the notification closes. * @type {function} */ - function createFromTemplate(template, elementID, options= {}) { + function createFromTemplate(title, template, elementID, options= {}) { // https://floating-ui.com/docs/tutorial options.allowedPlacements = options.allowedPlacements || ['top', 'bottom', 'left', 'right']; options.dismissOnClick = options.dismissOnClick === undefined ? true : options.dismissOnClick; if(!elementID){ elementID = 'notificationUIDefaultAnchor'; } - const tooltip = _createDomElementWithArrowElement(template, elementID, options); - tooltip.addClass('notification-ui-visible'); - let notification = (new Notification(tooltip, NOTIFICATION_TYPE_ARROW)); + const $tooltip = _createDomElementWithArrowElement(title, template, elementID, options); + $tooltip.addClass('notification-ui-visible'); + let notification = (new Notification($tooltip, NOTIFICATION_TYPE_ARROW)); if(options.autoCloseTimeS){ setTimeout(()=>{ @@ -228,10 +231,13 @@ define(function (require, exports, module) { } if(options.dismissOnClick){ - tooltip.click(()=>{ + $tooltip.click(()=>{ notification.close(CLOSE_REASON.CLICK_DISMISS); }); } + $tooltip.find(".notification-popup-close-button").click(()=>{ + notification.close(CLOSE_REASON.CLICK_DISMISS); + }); return notification; } @@ -287,7 +293,7 @@ define(function (require, exports, module) { WorkspaceManager.on(WorkspaceManager.EVENT_WORKSPACE_UPDATE_LAYOUT, tooltip.update); } - function _createDomElementWithArrowElement(domTemplate, elementID, options) { + function _createDomElementWithArrowElement(title, domTemplate, elementID, options) { notificationWidgetCount++; const onElement = document.getElementById(elementID); let arrowElement; @@ -297,18 +303,29 @@ define(function (require, exports, module) { if (typeof domTemplate === 'string' || domTemplate instanceof String){ textTemplate = domTemplate; } - let floatingDom = $(``); + const styleClass = NOTIFICATION_STYLES_CSS_CLASS[options.toastStyle] + || options.toastStyle; + let $floatingDom = $(``); if(!textTemplate && domTemplate){ - floatingDom.append($(domTemplate)); + $floatingDom.find(".notification-dialog-content").append($(domTemplate)); } if(onElement){ - arrowElement = $(`
`); - floatingDom.append(arrowElement); + arrowElement = $(`
`); + $floatingDom.append(arrowElement); } - $("body").append(floatingDom); - _updatePositions(floatingDom[0], onElement, arrowElement[0], options); - return floatingDom; + $("body").append($floatingDom); + _updatePositions($floatingDom[0], onElement, arrowElement[0], options); + return $floatingDom; } /** @@ -340,10 +357,11 @@ define(function (require, exports, module) { function createToastFromTemplate(title, template, options = {}) { options.dismissOnClick = options.dismissOnClick === undefined ? true : options.dismissOnClick; notificationWidgetCount++; + const styleClass = NOTIFICATION_STYLES_CSS_CLASS[options.toastStyle] + || options.toastStyle || NOTIFICATION_STYLES_CSS_CLASS.INFO; const widgetID = `notification-toast-${notificationWidgetCount}`, $NotificationPopup = $(Mustache.render(ToastPopupHtml, {id: widgetID, title: title, - containerStyle: NOTIFICATION_STYLES_CSS_CLASS[options.toastStyle] - || options.toastStyle || NOTIFICATION_STYLES_CSS_CLASS.INFO})); + containerStyle: styleClass})); $NotificationPopup.find(".notification-dialog-content") .append($(template));