🚧 Work in progress welcome page

This commit is contained in:
trickypr 2021-11-28 16:48:08 +11:00
parent 083c152450
commit 549b56df0e
11 changed files with 344 additions and 0 deletions

1
.prettierignore Normal file
View File

@ -0,0 +1 @@
engine/

12
.prettierrc Normal file
View File

@ -0,0 +1,12 @@
{
"semi": false,
"singleQuote": true,
"overrides": [
{
"files": "src/browser/app/profile/*.js",
"options": {
"semi": true
}
}
]
}

View File

@ -14,6 +14,10 @@
"ublock": {
"id": "uBlock0@raymondhill.net",
"url": "https://github.com/gorhill/uBlock/releases/download/1.39.0/uBlock0_1.39.0.firefox.xpi"
},
"newtab": {
"id": "newtab@browser.fushra.com",
"url": "https://github.com/focus-browser/newtab/releases/download/v1.0.0-a.2/newtab.zip"
}
}
}

View File

@ -0,0 +1,6 @@
// Note: You must have semicolons at the end of each line in user setting files
pref('browser.aboutwelcome.enabled', false);
pref('focus.welcome.enabled', true);
pref('focus.welcome.seen', false);

View File

@ -0,0 +1,54 @@
diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm
index 7bfc4ff7684931a656c0c1cd85a83082219e4f45..f88d4af15d7863d51b9f6894e24fa9ec6759a402 100644
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -3981,6 +3981,18 @@ BrowserGlue.prototype = {
);
},
+ /**
+ * Displays the welcome dialog. Trigured `_maybeShowDefaultBrowserPrompt`.
+ *
+ * @todo Provide documentation for implementing custom popups
+ * @patch FocusBrowser
+ */
+ _showWelcomeDialog() {
+ BrowserWindowTracker.getTopWindow().gDialogBox.open(
+ "chrome://focus/content/welcome.html"
+ );
+ },
+
async _maybeShowDefaultBrowserPrompt() {
// Highest priority is the upgrade dialog, which can include a "primary
// browser" request and is limited in various ways, e.g., major upgrades.
@@ -4038,6 +4050,30 @@ BrowserGlue.prototype = {
return;
}
+
+ // =========================================================================
+ // Focus browser welcome
+
+ const welcomeEnabledPref = 'focus.welcome.enabled'
+ const welcomeSeenPref = 'focus.welcome.seen'
+
+ // NOTE: Get bool prefs takes in two options, the pref string and a default
+ // value if it is not defined
+
+ // TODO: Add pref information to melon docs
+
+ const welcomeEnabled = Services.prefs.getBoolPref(welcomeEnabledPref, true)
+ const welcomeSeen = Services.prefs.getBoolPref(welcomeSeenPref, false)
+
+ if (welcomeEnabled && !welcomeSeen) {
+ this._showWelcomeDialog()
+ // TODO: When welcome is fully implemented, the following line should run
+ // Services.prefs.setBoolPref(welcomeSeenPref, true)
+ }
+
+ // =========================================================================
+
+
const willPrompt = await DefaultBrowserCheck.willCheckDefaultBrowser(
/* isStartupCheck */ true
);

View File

@ -0,0 +1,22 @@
diff --git a/browser/components/moz.build b/browser/components/moz.build
index aaae39b52f397623ba8153e5fdd079e43a16e09e..34bb8c3445ef292ffcd4a27e974465786dc147e6 100644
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -25,7 +25,6 @@ with Files("safebrowsing/**"):
with Files("controlcenter/**"):
BUG_COMPONENT = ("Firefox", "General")
-
DIRS += [
"about",
"aboutlogins",
@@ -61,6 +60,9 @@ DIRS += [
"urlbar",
]
+# Focus browser imports
+DIRS += ["welcome"]
+
DIRS += ["build"]
if CONFIG["NIGHTLY_BUILD"]:

View File

@ -0,0 +1,5 @@
focus.jar:
% content focus %content/focus/ contentaccessible=yes
content/focus/welcome.html
content/focus/welcome.css
content/focus/welcome.js

View File

@ -0,0 +1 @@
JAR_MANIFESTS += ["jar.mn"]

View File

@ -0,0 +1,54 @@
body {
width: 504px;
height: 504px;
display: flex;
position: relative;
flex-flow: row nowrap;
height: 100%;
min-height: 500px;
overflow: hidden;
}
.page {
display: none;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
align-content: center;
width: 100%;
margin: 64px;
}
.card h3 {
font-size: 0.75rem;
}
#themeList {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
gap: 8px;
margin-bottom: 8px;
}
#themeList .card {
width: 140px;
display: flex;
flex-direction: column;
align-items: center;
border: 2px solid transparent;
transition: all 250ms ease-in-out;
}
#themeList .card.selected {
border: 2px solid var(--in-content-item-selected);
}
h2,
p {
margin: 8px 0;
}

View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta
http-equiv="Content-Security-Policy"
content="default-src chrome:; object-src 'none'"
/>
<meta name="referrer" content="no-referrer" />
<link
rel="stylesheet"
type="text/css"
href="chrome://global/skin/in-content/common.css"
/>
<link rel="localization" href="branding/brand.ftl" />
<link rel="stylesheet" href="chrome://focus/content/welcome.css" />
</head>
<body>
<div class="page" id="welcome">
<h2>Welcome to Focus Browser</h2>
<p>Lets get you setup</p>
<button id="welcomeNext" class="primary">Get started</button>
</div>
<div class="page" id="import">
<h2>Import your stuff</h2>
<p>
TODO: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
<br />
<button class="primary">Import from previous browser</button>
<button class="text-link" id="importNext">Not now</button>
</div>
<div class="page" id="theme">
<h2>Chose a theme</h2>
<div id="themeList"></div>
<button id="themeNext" class="primary">Continue</button>
</div>
<div class="page" id="search">
<h2>Chose a search engine</h2>
<p>TODO: Search engines here</p>
<button id="searchNext" class="primary">Done</button>
</div>
<script src="./welcome.js"></script>
</body>
</html>

View File

@ -0,0 +1,131 @@
const { XPCOMUtils } = ChromeUtils.import(
'resource://gre/modules/XPCOMUtils.jsm'
)
XPCOMUtils.defineLazyModuleGetters(this, {
AddonManager: 'resource://gre/modules/AddonManager.jsm',
})
class Page {
/**
* A basic controller for individual pages
* @param {string} id The id of the element that represents this page.
*/
constructor(id) {
this.element = document.getElementById(id)
this.nextEl = document.getElementById(`${id}Next`)
this.nextEl.addEventListener('click', () => {
this.pages.next()
})
}
/**
*
* @param {Pages} pages The pages wrapper
*/
setPages(pages) {
this.pages = pages
}
hide() {
this.element.style.display = 'none'
}
show() {
this.element.style.display = ''
}
}
class Themes extends Page {
constructor(id) {
super(id)
this.loadThemes()
}
async loadThemes() {
const themes = (await AddonManager.getAddonsByTypes(['theme'])).filter(
(theme) => !theme.id.includes('colorway')
)
const themeList = document.getElementById('themeList')
const themeElements = []
let selectedTheme = ''
console.log(themes)
themes.forEach((theme) => {
const container = document.createElement('div')
container.classList.add('card')
if (theme.isActive) {
container.classList.add('selected')
selectedTheme = theme.id
}
container.addEventListener('click', () => {
themeElements.forEach((el) => el.classList.remove('selected'))
container.classList.add('selected')
selectedTheme = theme.id
theme.enable()
})
const img = document.createElement('img')
img.src = theme.icons['32']
img.classList.add('card-heading-image')
const name = document.createElement('h3')
name.textContent = theme.name
container.appendChild(img)
container.appendChild(name)
themeList.appendChild(container)
themeElements.push(container)
})
}
}
class Pages {
/**
* A wrapper around all pages
* @param {Page[]} pages The pages
*/
constructor(pages) {
this.pages = pages
this.currentPage = 0
this.pages.forEach((page) => page.setPages(this))
this._displayCurrentPage()
}
next() {
this.currentPage++
if (this.currentPage >= this.pages.length) {
// We can use internal js apis to close the window
close()
return
}
this._displayCurrentPage()
}
_displayCurrentPage() {
for (const page of this.pages) {
page.hide()
}
this.pages[this.currentPage].show()
}
}
const pages = new Pages([
new Page('welcome'),
new Page('import'),
new Themes('theme'),
new Page('search'),
])