Update dependencies, add macOS Aqua theme, and patch up Settings page

This commit is contained in:
Marquis Kurt 2019-09-30 18:18:38 -04:00
parent e3846d4872
commit eb2399201e
No known key found for this signature in database
GPG Key ID: 725636D259F5402D
11 changed files with 502 additions and 331 deletions

158
package-lock.json generated
View File

@ -1283,9 +1283,9 @@
"dev": true
},
"@types/debug": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.4.tgz",
"integrity": "sha512-D9MyoQFI7iP5VdpEyPZyjjqIJ8Y8EDNQFIFVLOmeg1rI1xiHOChyUPMPRUVfqFCerxfE+yS3vMyj37F6IdtOoQ==",
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
"integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==",
"dev": true
},
"@types/emoji-mart": {
@ -2154,27 +2154,27 @@
}
},
"app-builder-bin": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.4.2.tgz",
"integrity": "sha512-E9VvUrZm60oLl0rvLw/ErvZiEOIHkulZbJ9C9TWMD4ftNrkXFc2+a5JGlD19Bwvj329d4qz91zs/hWD01q18TQ==",
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.4.3.tgz",
"integrity": "sha512-qMhayIwi3juerQEVJMQ76trObEbfQT0nhUdxZz9a26/3NLT3pE6awmQ8S1cEnrGugaaM5gYqR8OElcDezfmEsg==",
"dev": true
},
"app-builder-lib": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-21.1.5.tgz",
"integrity": "sha512-hLsSVSstMTq33a9jbBStrF0e+fa6eWXWIpsatPvHnJlkjx7dAZ5d2cZPe/1bAO3bCL3afpRl5j+HU853eGfDCg==",
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-21.2.0.tgz",
"integrity": "sha512-aOX/nv77/Bti6NymJDg7p9T067xD8m1ipIEJR7B4Mm1GsJWpMm9PZdXtCRiMNRjHtQS5KIljT0g17781y6qn5A==",
"dev": true,
"requires": {
"7zip-bin": "~5.0.3",
"@develar/schema-utils": "~2.1.0",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.9",
"builder-util": "21.1.5",
"builder-util": "21.2.0",
"builder-util-runtime": "8.3.0",
"chromium-pickle-js": "^0.2.0",
"debug": "^4.1.1",
"ejs": "^2.6.2",
"electron-publish": "21.1.5",
"electron-publish": "21.2.0",
"fs-extra": "^8.1.0",
"hosted-git-info": "^2.7.1",
"is-ci": "^2.0.0",
@ -2184,7 +2184,7 @@
"minimatch": "^3.0.4",
"normalize-package-data": "^2.5.0",
"read-config-file": "5.0.0",
"sanitize-filename": "^1.6.1",
"sanitize-filename": "^1.6.2",
"semver": "^6.3.0",
"temp-file": "^3.3.4"
},
@ -2216,9 +2216,9 @@
}
},
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
"dev": true
},
"is-ci": {
@ -3542,14 +3542,14 @@
"dev": true
},
"builder-util": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-21.1.5.tgz",
"integrity": "sha512-RBr06OnoTKTkg0W7Om2dnuKe8I82CiciU9EdsNnLO8DAfH0ZVCPsVpc3qYmr7g/7cH3zXA3yyQP73QDGNpbVYQ==",
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/builder-util/-/builder-util-21.2.0.tgz",
"integrity": "sha512-Nd6CUb6YgDY8EXAXEIegx+1kzKqyFQ5ZM5BoYkeunAlwz/zDJoH1UCyULjoS5wQe5czNClFQy07zz2bzYD0Z4A==",
"dev": true,
"requires": {
"7zip-bin": "~5.0.3",
"@types/debug": "^4.1.4",
"app-builder-bin": "3.4.2",
"app-builder-bin": "3.4.3",
"bluebird-lst": "^1.0.9",
"builder-util-runtime": "8.3.0",
"chalk": "^2.4.2",
@ -3557,7 +3557,7 @@
"fs-extra": "^8.1.0",
"is-ci": "^2.0.0",
"js-yaml": "^3.13.1",
"source-map-support": "^0.5.12",
"source-map-support": "^0.5.13",
"stat-mode": "^0.3.0",
"temp-file": "^3.3.4"
},
@ -3589,9 +3589,9 @@
}
},
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
"dev": true
},
"is-ci": {
@ -3610,9 +3610,9 @@
"dev": true
},
"source-map-support": {
"version": "0.5.12",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
"integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
@ -3747,9 +3747,9 @@
"dev": true
},
"normalize-url": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.3.0.tgz",
"integrity": "sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ==",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
"dev": true
}
}
@ -6120,18 +6120,18 @@
}
},
"dmg-builder": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-21.1.5.tgz",
"integrity": "sha512-o9rZua7mzNzZIo9SZJi57ZXe4zjNaajxEJ0LO/8k2z8Q2CL57RIaJZ95sA6G0dC1/g5Gm4cmW3O5nv9Ur8Ayow==",
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-21.2.0.tgz",
"integrity": "sha512-9cJEclnGy7EyKFCoHDYDf54pub/t92CQapyiUxU0w9Bj2vUvfoDagP1PMiX4XD5rPp96141h9A+QN0OB4VgvQg==",
"dev": true,
"requires": {
"app-builder-lib": "~21.1.5",
"app-builder-lib": "~21.2.0",
"bluebird-lst": "^1.0.9",
"builder-util": "~21.1.5",
"builder-util": "~21.2.0",
"fs-extra": "^8.1.0",
"iconv-lite": "^0.5.0",
"js-yaml": "^3.13.1",
"sanitize-filename": "^1.6.1"
"sanitize-filename": "^1.6.2"
},
"dependencies": {
"fs-extra": {
@ -6146,9 +6146,9 @@
}
},
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
"dev": true
},
"iconv-lite": {
@ -6358,15 +6358,15 @@
"dev": true
},
"ejs": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.2.tgz",
"integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q==",
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.1.tgz",
"integrity": "sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==",
"dev": true
},
"electron": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/electron/-/electron-5.0.8.tgz",
"integrity": "sha512-wkUVE2GaYCsqQTsISSHWkIkcdpwLwZ1jhzAXSFFoSzsTgugmzhX60rJjIccotUmZ0iPzw+u4ahfcaJ0eslrPNQ==",
"version": "6.0.10",
"resolved": "https://registry.npmjs.org/electron/-/electron-6.0.10.tgz",
"integrity": "sha512-eTFm6uTn7NKZE1OtSZSOxNuOrCXXeUR0U3vdF3R00byB7mrNe5AOaXEDDMwtzRGGY1jMuUX9Z7RvgXaCXRYSmw==",
"dev": true,
"requires": {
"@types/node": "^10.12.18",
@ -6375,30 +6375,30 @@
},
"dependencies": {
"@types/node": {
"version": "10.14.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.13.tgz",
"integrity": "sha512-yN/FNNW1UYsRR1wwAoyOwqvDuLDtVXnaJTZ898XIw/Q5cCaeVAlVwvsmXLX5PuiScBYwZsZU4JYSHB3TvfdwvQ==",
"version": "10.14.19",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.19.tgz",
"integrity": "sha512-j6Sqt38ssdMKutXBUuAcmWF8QtHW1Fwz/mz4Y+Wd9mzpBiVFirjpNQf363hG5itkG+yGaD+oiLyb50HxJ36l9Q==",
"dev": true
}
}
},
"electron-builder": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-21.1.5.tgz",
"integrity": "sha512-2tEgBESGWQ661dC9/rZlpbtmhlofoNPwnkO6KUuCZUBYpFMRvpMzH2IF7vQYsCst78yxnrV0CtiBePhM1i+DfA==",
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-21.2.0.tgz",
"integrity": "sha512-x8EXrqFbAb2L3N22YlGar3dGh8vwptbB3ovo3OF6K7NTpcsmM2zEoJv7GhFyX73rNzSG2HaWpXwGAtOp2JWiEw==",
"dev": true,
"requires": {
"app-builder-lib": "21.1.5",
"app-builder-lib": "21.2.0",
"bluebird-lst": "^1.0.9",
"builder-util": "21.1.5",
"builder-util": "21.2.0",
"builder-util-runtime": "8.3.0",
"chalk": "^2.4.2",
"dmg-builder": "21.1.5",
"dmg-builder": "21.2.0",
"fs-extra": "^8.1.0",
"is-ci": "^2.0.0",
"lazy-val": "^1.0.4",
"read-config-file": "5.0.0",
"sanitize-filename": "^1.6.1",
"sanitize-filename": "^1.6.2",
"update-notifier": "^3.0.1",
"yargs": "^13.3.0"
},
@ -6453,9 +6453,9 @@
"dev": true
},
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
"dev": true
},
"is-ci": {
@ -6478,9 +6478,9 @@
}
},
"p-limit": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
"integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
"integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
@ -6639,13 +6639,13 @@
}
},
"electron-publish": {
"version": "21.1.5",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-21.1.5.tgz",
"integrity": "sha512-EgFxZJBrb+EBUcEwg8RNKouoBaOEpACnjLi+ipUsk72x+/6kzhcofAYBchIkGns7meengoXy7QdoiThgpr6rew==",
"version": "21.2.0",
"resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-21.2.0.tgz",
"integrity": "sha512-mWavuoWJe87iaeKd0I24dNWIaR+0yRzshjNVqGyK019H766fsPWl3caQJnVKFaEyrZRP397v4JZVG0e7s16AxA==",
"dev": true,
"requires": {
"bluebird-lst": "^1.0.9",
"builder-util": "~21.1.5",
"builder-util": "~21.2.0",
"builder-util-runtime": "8.3.0",
"chalk": "^2.4.2",
"fs-extra": "^8.1.0",
@ -6665,9 +6665,9 @@
}
},
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
"dev": true
},
"mime": {
@ -17024,9 +17024,9 @@
},
"dependencies": {
"dotenv": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.0.0.tgz",
"integrity": "sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.1.0.tgz",
"integrity": "sha512-GUE3gqcDCaMltj2++g6bRQ5rBJWtkWTmqmD0fo1RnnMuUqHNCt2oTPeDnS9n6fKYvlhn7AeBkb38lymBtWBQdA==",
"dev": true
},
"dotenv-expand": {
@ -17047,9 +17047,9 @@
}
},
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
"dev": true
}
}
@ -18208,9 +18208,9 @@
}
},
"sanitize-filename": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.2.tgz",
"integrity": "sha512-cmTzND7RMxUB+f7gI+4+KAVHWEg0lfXvQJdko+FXDP5bNbGIdx4KMP5pX6lv5jfT9jSf6OBbjyxjFtZQwYA/ig==",
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
"integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
"dev": true,
"requires": {
"truncate-utf8-bytes": "^1.0.0"
@ -19460,9 +19460,9 @@
}
},
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
"dev": true
}
}

View File

@ -19,8 +19,8 @@
"@types/react-router-dom": "^4.3.4",
"@types/react-swipeable-views": "latest",
"axios": "^0.19.0",
"electron": "^5.0.8",
"electron-builder": "^21.1.5",
"electron": "^6.0.10",
"electron-builder": "^21.2.0",
"emoji-mart": "^2.11.1",
"file-dialog": "^0.0.7",
"material-ui-pickers": "^2.2.4",

View File

@ -138,10 +138,10 @@ function createWindow() {
webPreferences: {nodeIntegration: true},
// Set some preferences that are specific to macOS.
titleBarStyle: 'hidden',
vibrancy: catalina()? "sidebar": systemPreferences.isDarkMode()? "ultra-dark": "light",
titleBarStyle: 'hiddenInset',
vibrancy: "sidebar",
transparent: darwin(),
backgroundColor: darwin()? "#80FFFFFF": "#FFF"
backgroundColor: darwin()? "#80000000": "#FFF"
}
);
@ -151,16 +151,22 @@ function createWindow() {
// Load the main app and open the index page.
mainWindow.loadURL("hyperspace://hyperspace/app/");
// Watch for a change in macOS's dark mode and reload the window to apply changes
// Watch for a change in macOS's dark mode and reload the window to apply changes, as well as accent color
if (darwin()) {
systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', () => {
if (mainWindow != null) {
if (!catalina()) {
mainWindow.setVibrancy(systemPreferences.isDarkMode()? "ultra-dark": "light");
if (mainWindow != null) {
if (!catalina()) {
mainWindow.setVibrancy(systemPreferences.isDarkMode() ? "ultra-dark" : "light");
}
mainWindow.webContents.reload();
}
mainWindow.webContents.reload();
}
})
});
systemPreferences.subscribeNotification('AppleColorPreferencesChangedNotification', () => {
if (mainWindow != null) {
mainWindow.webContents.reload();
}
});
}
// Delete the window when closed

View File

@ -28,10 +28,11 @@
<link href="%PUBLIC_URL%/splashes/apple_splash_640.png" sizes="640x1136" rel="apple-touch-startup-image" />
<style>
body::-webkit-scrollbar {
display: none;
width: 0 !important;
}
body {
scrollbar-width: none;
overflow: -moz-scrollbars-none;
-ms-overflow-style: none;
}
</style>
<title>Hyperspace</title>

View File

@ -29,10 +29,10 @@ export const styles = (theme: Theme) =>
zIndex: 1000,
verticalAlign: "middle",
WebkitUserSelect: "none",
WebkitAppRegion: "drag"
WebkitAppRegion: "drag",
color: theme.palette.getContrastText(theme.palette.primary.main)
},
titleBarText: {
color: theme.palette.common.white,
fontSize: 12,
paddingTop: 2,
paddingBottom: 1
@ -46,7 +46,9 @@ export const styles = (theme: Theme) =>
borderBottomColor: darken(theme.palette.primary.dark, 0.2),
borderBottomWidth: 1,
borderBottomStyle: isDarwinApp() ? "solid" : "none",
boxShadow: isDarwinApp() ? "none" : theme.shadows["4"]
boxShadow: isDarwinApp() ? "none" : theme.shadows["4"],
WebkitUserSelect: isDarwinApp() ? "none" : "inherit",
WebkitAppRegion: isDarwinApp() ? "drag" : "inherit"
},
appBarMenuButton: {
marginLeft: -12,

View File

@ -245,7 +245,10 @@ export class AppLayout extends Component<any, IAppLayoutState> {
if (isDarwinApp()) {
return (
<div className={classes.titleBarRoot}>
<Typography className={classes.titleBarText}>
<Typography
className={classes.titleBarText}
color="inherit"
>
{this.state.brandName
? this.state.brandName
: "Hyperspace"}{" "}

View File

@ -65,6 +65,7 @@ interface IPostProps {
post: Status;
classes: any;
client: Mastodon;
threadHeader: boolean;
}
interface IPostState {
@ -621,7 +622,11 @@ export class Post extends React.Component<any, IPostState> {
const post = this.state.post;
return (
<Zoom in={true}>
<Card className={classes.post} id={`post_${post.id}`}>
<Card
className={classes.post}
id={`post_${post.id}`}
elevation={this.props.threadHeader ? 0 : 1}
>
<CardHeader
avatar={
<LinkableAvatar
@ -653,7 +658,7 @@ export class Post extends React.Component<any, IPostState> {
dangerouslySetInnerHTML={{
__html: this.getReblogAuthors(post)
}}
></Typography>
/>
}
subheader={moment(post.created_at).format(
"MMMM Do YYYY [at] h:mm A"

View File

@ -65,6 +65,12 @@ export const styles = (theme: Theme) =>
paddingLeft: theme.spacing.unit * 2,
paddingRight: theme.spacing.unit * 2
},
pageMinimalBreak: {
height: isAppbarExpanded() ? 80 : 64,
[theme.breakpoints.up("md")]: {
height: isAppbarExpanded() ? 88 : 64
}
},
pageHeroBackground: {
position: "relative",
height: "intrinsic",
@ -72,7 +78,10 @@ export const styles = (theme: Theme) =>
width: "100%",
color: theme.palette.common.white,
zIndex: 1,
top: isAppbarExpanded() ? 80 : 64
top: isAppbarExpanded() ? 80 : 64,
[theme.breakpoints.up("md")]: {
top: isAppbarExpanded() ? 88 : 64
}
},
pageHeroBackgroundImage: {
position: "absolute",
@ -156,16 +165,16 @@ export const styles = (theme: Theme) =>
pageProfileNameEmoji: {
minHeight: theme.typography.h4.fontSize,
fontWeight: theme.typography.fontWeightMedium,
'& img': {
height: theme.typography.h4.fontSize,
"& img": {
height: theme.typography.h4.fontSize
}
},
pageProfileBioEmoji: {
height: '0.875rem',
'& img': {
height: '0.875rem',
height: "0.875rem",
"& img": {
height: "0.875rem",
paddingLeft: 4,
paddingRight: 4,
paddingRight: 4
}
},
pageProfileStatsDiv: {

View File

@ -21,7 +21,10 @@ import {
DialogContentText,
Grid,
Theme,
Typography
Typography,
Avatar,
Toolbar,
Tooltip
} from "@material-ui/core";
import { styles } from "./PageLayout.styles";
import {
@ -45,7 +48,7 @@ import {
getDarkModeFromSystem
} from "../utilities/themes";
import { Visibility } from "../types/Visibility";
import { LinkableButton } from "../interfaces/overrides";
import { LinkableButton, LinkableIconButton } from "../interfaces/overrides";
import OpenInNewIcon from "@material-ui/icons/OpenInNew";
import DevicesIcon from "@material-ui/icons/Devices";
@ -60,6 +63,9 @@ import RefreshIcon from "@material-ui/icons/Refresh";
import UndoIcon from "@material-ui/icons/Undo";
import DomainDisabledIcon from "@material-ui/icons/DomainDisabled";
import { Config } from "../types/Config";
import { Account } from "../types/Account";
import Mastodon from "megalodon";
import { isDarwinApp } from "../utilities/desktop";
interface ISettingsState {
darkModeEnabled: boolean;
@ -75,12 +81,20 @@ interface ISettingsState {
defaultVisibility: Visibility;
brandName: string;
federated: boolean;
currentUser?: Account;
}
class SettingsPage extends Component<any, ISettingsState> {
client: Mastodon;
constructor(props: any) {
super(props);
this.client = new Mastodon(
localStorage.getItem("access_token") as string,
(localStorage.getItem("baseurl") as string) + "/api/v1"
);
this.state = {
darkModeEnabled: getUserDefaultBool("darkModeEnabled"),
systemDecidesDarkMode: getUserDefaultBool("systemDecidesDarkMode"),
@ -123,14 +137,31 @@ class SettingsPage extends Component<any, ISettingsState> {
console.error(err.message);
});
this.getFederatedStatus();
console.log(getDarkModeFromSystem());
let acct = localStorage.getItem("account");
if (acct) {
this.setState({ currentUser: JSON.parse(acct) });
} else {
this.client
.get("/accounts/verify_credentials")
.then((resp: any) => {
let data: Account = resp.data;
this.setState({ currentUser: data });
})
.catch((err: Error) => {
this.props.enqueueSnackbar(
"Couldn't find profile info: " + err.name
);
console.error(err.message);
});
}
}
getFederatedStatus() {
getConfig().then((result: any) => {
if (result !== undefined) {
let config: Config = result;
console.log(config.federation.allowPublicPosts === false);
console.log(!config.federation.allowPublicPosts);
this.setState({
federated: config.federation.allowPublicPosts
});
@ -433,224 +464,276 @@ class SettingsPage extends Component<any, ISettingsState> {
render() {
const { classes } = this.props;
return (
<div className={classes.pageLayoutConstraints}>
<ListSubheader>Appearance</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<DevicesIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Match system appearance"
secondary="Obey light/dark theme from your system"
<div>
<div className={classes.pageLayoutMinimalConstraints}>
{this.state.currentUser ? (
<div className={classes.pageHeroBackground}>
<div
className={classes.pageHeroBackgroundImage}
style={{
backgroundImage: `url("${this.state.currentUser.header_static}")`
}}
/>
<ListItemSecondaryAction>
<Switch
checked={this.state.systemDecidesDarkMode}
onChange={this.toggleSystemDarkMode}
<div className={classes.profileContent}>
<br />
<Avatar
className={classes.profileAvatar}
src={this.state.currentUser.avatar_static}
/>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemAvatar>
<Brightness3Icon color="action" />
</ListItemAvatar>
<ListItemText
primary="Dark mode"
secondary="Toggles light or dark theme"
/>
<ListItemSecondaryAction>
<Switch
disabled={this.state.systemDecidesDarkMode}
checked={this.state.darkModeEnabled}
onChange={this.toggleDarkMode}
/>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemAvatar>
<PaletteIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Interface theme"
secondary="The color palette used for the interface"
/>
<ListItemSecondaryAction>
<Button onClick={this.toggleThemeDialog}>
Set theme
</Button>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
<br />
<ListSubheader>Your Account</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<AccountEditIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Edit your profile"
secondary="Change your bio, display name, and images"
/>
<ListItemSecondaryAction>
<LinkableButton to="/you">Edit</LinkableButton>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemAvatar>
<DomainDisabledIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Manage blocked servers"
secondary="View and manage servers that you've blocked"
/>
<ListItemSecondaryAction>
<LinkableButton to="/blocked">
Manage
</LinkableButton>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemAvatar>
<MastodonIcon color="action" />
</ListItemAvatar>
<ListItemText primary="Configure on Mastodon" />
<ListItemSecondaryAction>
<IconButton
href={
(localStorage.getItem(
"baseurl"
) as string) + "/settings/preferences"
}
target="_blank"
rel="noreferrer"
<div
className={classes.profileUserBox}
style={{ margin: "auto" }}
>
<OpenInNewIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
<br />
<ListSubheader>Composer</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<VisibilityIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Default visibility"
secondary="New posts in composer will use this visiblity"
/>
<ListItemSecondaryAction>
<Button onClick={this.toggleVisibilityDialog}>
Change
</Button>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
<br />
<ListSubheader>Notifications</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<NotificationsIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Enable push notifications"
secondary={
getUserDefaultBool("userDeniedNotification")
? "Check your browser's notification permissions."
: browserSupportsNotificationRequests()
? "Send a push notification when not focused."
: "Notifications aren't supported."
}
/>
<ListItemSecondaryAction>
<Switch
checked={
this.state.pushNotificationsEnabled
}
onChange={this.togglePushNotifications}
disabled={
!browserSupportsNotificationRequests() ||
getUserDefaultBool(
"userDeniedNotification"
)
}
/>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemAvatar>
<BellAlertIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Notification badge counts all notifications"
secondary={
"Counts all notifications, read or unread."
}
/>
<ListItemSecondaryAction>
<Switch
checked={this.state.badgeDisplaysAllNotifs}
onChange={this.toggleBadgeCount}
/>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
<br />
<ListSubheader>Advanced</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<RefreshIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Refresh settings"
secondary="Reset the settings to defaults."
/>
<ListItemSecondaryAction>
<Button
onClick={() =>
this.toggleResetSettingsDialog()
}
>
Refresh
</Button>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemAvatar>
<UndoIcon color="action" />
</ListItemAvatar>
<ListItemText
primary={`Reset ${this.state.brandName}`}
secondary="Deletes all data and resets the app"
/>
<ListItemSecondaryAction>
<Button
onClick={() => this.toggleResetDialog()}
>
Reset
</Button>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
{this.showThemeDialog()}
{this.showVisibilityDialog()}
{this.showResetDialog()}
{this.showResetSettingsDialog()}
<Typography
variant="h4"
color="inherit"
component="h1"
>
{this.state.currentUser.display_name ||
this.state.currentUser.username}
</Typography>
<Typography
color="inherit"
variant="h6"
component="p"
>
@{this.state.currentUser.acct}
</Typography>
</div>
<div className={classes.pageGrow} />
<Toolbar>
<Tooltip title="Edit Profile">
<LinkableIconButton
to={"/you"}
color="inherit"
>
<AccountEditIcon />
</LinkableIconButton>
</Tooltip>
<Tooltip title="Manage blocked servers">
<LinkableIconButton
to={"/blocked"}
color="inherit"
>
<DomainDisabledIcon />
</LinkableIconButton>
</Tooltip>
<Tooltip title="Configure on Mastodon">
<IconButton
href={
(localStorage.getItem(
"baseurl"
) as string) +
"/settings/preferences"
}
target="_blank"
rel="noreferrer"
color="inherit"
>
<MastodonIcon />
</IconButton>
</Tooltip>
</Toolbar>
</div>
</div>
) : null}
<div className={classes.pageContentLayoutConstraints}>
<ListSubheader>Appearance</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<DevicesIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Match system appearance"
secondary="Obey light/dark theme from your system"
/>
<ListItemSecondaryAction>
<Switch
checked={
this.state.systemDecidesDarkMode
}
onChange={this.toggleSystemDarkMode}
/>
</ListItemSecondaryAction>
</ListItem>
{!isDarwinApp() ||
(isDarwinApp() &&
!this.state.systemDecidesDarkMode) ? (
<ListItem>
<ListItemAvatar>
<Brightness3Icon color="action" />
</ListItemAvatar>
<ListItemText
primary="Dark mode"
secondary="Toggles light or dark theme"
/>
<ListItemSecondaryAction>
<Switch
disabled={
this.state
.systemDecidesDarkMode
}
checked={
this.state.darkModeEnabled
}
onChange={this.toggleDarkMode}
/>
</ListItemSecondaryAction>
</ListItem>
) : null}
<ListItem>
<ListItemAvatar>
<PaletteIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Interface theme"
secondary="The color palette used for the interface"
/>
<ListItemSecondaryAction>
<Button
onClick={this.toggleThemeDialog}
>
Set theme
</Button>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
<br />
<ListSubheader>Composer</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<VisibilityIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Default visibility"
secondary="New posts in composer will use this visiblity"
/>
<ListItemSecondaryAction>
<Button
onClick={
this.toggleVisibilityDialog
}
>
Change
</Button>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
<br />
<ListSubheader>Notifications</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<NotificationsIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Enable push notifications"
secondary={
getUserDefaultBool(
"userDeniedNotification"
)
? "Check your browser's notification permissions."
: browserSupportsNotificationRequests()
? "Send a push notification when not focused."
: "Notifications aren't supported."
}
/>
<ListItemSecondaryAction>
<Switch
checked={
this.state
.pushNotificationsEnabled
}
onChange={
this.togglePushNotifications
}
disabled={
!browserSupportsNotificationRequests() ||
getUserDefaultBool(
"userDeniedNotification"
)
}
/>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemAvatar>
<BellAlertIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Notification badge counts all notifications"
secondary={
"Counts all notifications, read or unread."
}
/>
<ListItemSecondaryAction>
<Switch
checked={
this.state
.badgeDisplaysAllNotifs
}
onChange={this.toggleBadgeCount}
/>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
<br />
<ListSubheader>Advanced</ListSubheader>
<Paper className={classes.pageListConstraints}>
<List>
<ListItem>
<ListItemAvatar>
<RefreshIcon color="action" />
</ListItemAvatar>
<ListItemText
primary="Refresh settings"
secondary="Reset the settings to defaults."
/>
<ListItemSecondaryAction>
<Button
onClick={() =>
this.toggleResetSettingsDialog()
}
>
Refresh
</Button>
</ListItemSecondaryAction>
</ListItem>
<ListItem>
<ListItemAvatar>
<UndoIcon color="action" />
</ListItemAvatar>
<ListItemText
primary={`Reset ${this.state.brandName}`}
secondary="Deletes all data and resets the app"
/>
<ListItemSecondaryAction>
<Button
onClick={() =>
this.toggleResetDialog()
}
>
Reset
</Button>
</ListItemSecondaryAction>
</ListItem>
</List>
</Paper>
{this.showThemeDialog()}
{this.showVisibilityDialog()}
{this.showResetDialog()}
{this.showResetSettingsDialog()}
</div>
</div>
</div>
);
}

View File

@ -8,14 +8,14 @@ import {
deepOrange,
indigo,
lightBlue,
orange,
blue,
amber,
pink,
brown,
blueGrey
pink
} from "@material-ui/core/colors";
import { isDarwinApp } from "../utilities/desktop";
import {
isDarkMode,
isDarwinApp,
getDarwinAccentColor
} from "../utilities/desktop";
/**
* Basic theme colors for Hyperspace.
@ -159,3 +159,47 @@ export const themes = [
blissTheme,
attractTheme
];
/**
* Get the accent color from System Preferences.
*/
function getAquaAccentColor() {
switch (getDarwinAccentColor()) {
case 0:
return isDarkMode() ? "#ff453a" : "#FF3B30";
case 1:
return isDarkMode() ? "#ff9f0a" : "#ff9500";
case 2:
return isDarkMode() ? "#ffd60a" : "#ffcc00";
case 3:
return isDarkMode() ? "#32d74b" : "#28cd41";
case 5:
return isDarkMode() ? "#bf5af2" : "#af52de";
case 6:
return isDarkMode() ? "#ff375f" : "#ff2d55";
case -1:
return isDarkMode() ? "#98989d" : "#8e8e93";
default:
return isDarkMode() ? "#0A84FF" : "#007AFF";
}
}
/**
* Inject macOS themes and watch for changes.
*/
if (isDarwinApp()) {
const aquaTheme: HyperspaceTheme = {
key: "aquaTheme",
name: "Aqua (Dynamic)",
palette: {
primary: {
main: isDarkMode() ? "#353538" : "#EEEEEE"
},
secondary: {
main: getAquaAccentColor()
}
}
};
themes.unshift(aquaTheme);
}

View File

@ -29,3 +29,21 @@ export function isDarkMode() {
const { remote } = eWin.require("electron");
return remote.systemPreferences.isDarkMode();
}
/**
* Get the accent color from macOS.
*
* Note that the colors will go from left to right, starting from zero (eg.: -1 = Graphite, 0 = Red, 1 = Orange, etc.).
* Since AppleAccentColor might return an empty string for the blue color, -2 is used instead.
*
* @returns The corresponding integer for the accent color
*/
export function getDarwinAccentColor(): number {
const eWin = window as ElectronWindow;
const { remote } = eWin.require("electron");
const themeInteger = remote.systemPreferences.getUserDefault(
"AppleAccentColor",
"string"
);
return themeInteger === "" ? -2 : parseInt(themeInteger);
}