Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>tags/v14.0.0beta1
@@ -12,6 +12,7 @@ | |||
# ignore all apps except core ones | |||
/apps*/* | |||
!/apps/accessibility | |||
!/apps/comments | |||
!/apps/dav | |||
!/apps/files |
@@ -0,0 +1,12 @@ | |||
{ | |||
"presets": [ | |||
[ | |||
"env", | |||
{ | |||
"targets": { | |||
"browsers": ["last 2 versions", "not ie <= 11"] | |||
} | |||
} | |||
] | |||
] | |||
} |
@@ -0,0 +1,9 @@ | |||
root = true | |||
[*] | |||
charset = utf-8 | |||
indent_style = tab | |||
indent_size = 4 | |||
end_of_line = lf | |||
insert_final_newline = true | |||
trim_trailing_whitespace = true |
@@ -0,0 +1,16 @@ | |||
module.exports = { | |||
env: { | |||
browser: true, | |||
es6: true | |||
}, | |||
extends: 'eslint:recommended', | |||
parserOptions: { | |||
sourceType: 'module' | |||
}, | |||
rules: { | |||
indent: ['error', 'tab'], | |||
'linebreak-style': ['error', 'unix'], | |||
quotes: ['error', 'single'], | |||
semi: ['error', 'always'] | |||
} | |||
}; |
@@ -0,0 +1,12 @@ | |||
.DS_Store | |||
node_modules/ | |||
dist/ | |||
npm-debug.log | |||
yarn-error.log | |||
# Editor directories and files | |||
.idea | |||
*.suo | |||
*.ntvs* | |||
*.njsproj | |||
*.sln |
@@ -0,0 +1,3 @@ | |||
{ | |||
"esversion": 6 | |||
} |
@@ -0,0 +1,26 @@ | |||
all: dev-setup build-js-production | |||
dev-setup: clean clean-dev npm-init | |||
npm-init: | |||
npm install | |||
npm-update: | |||
npm update | |||
build-js: | |||
npm run dev | |||
build-js-production: | |||
npm run build | |||
watch-js: | |||
npm run watch | |||
clean: | |||
rm -f js/accessibility.js | |||
rm -f js/accessibility.js.map | |||
clean-dev: | |||
rm -rf node_modules | |||
@@ -0,0 +1,22 @@ | |||
# Accessibility ♿ | |||
> This app provide multiple features to ease the use of nextcloud. | |||
## Build Setup | |||
``` bash | |||
# install dependencies | |||
make dev-setup | |||
# build for development | |||
make build-js | |||
# build for development and watch edits | |||
make watch-js | |||
# build for production with minification | |||
make build-js-production | |||
# clean output files | |||
make clean | |||
``` |
@@ -0,0 +1,24 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @author John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
$app = new \OCA\Accessibility\AppInfo\Application(); |
@@ -0,0 +1,22 @@ | |||
<?xml version="1.0"?> | |||
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd"> | |||
<id>accessibility</id> | |||
<name>Accessibility</name> | |||
<summary>Accessibility options for nextcloud</summary> | |||
<description><![CDATA[Provides multiple accessibilities options to ease your use of nextcloud]]></description> | |||
<version>1.0.0</version> | |||
<licence>agpl</licence> | |||
<author>John Molakvoæ</author> | |||
<namespace>Accessibility</namespace> | |||
<category>accessibility</category> | |||
<dependencies> | |||
<nextcloud min-version="14" max-version="14"/> | |||
</dependencies> | |||
<default_enable/> | |||
<bugs>https://github.com/nextcloud/server/issues</bugs> | |||
<settings> | |||
<personal>OCA\Accessibility\Settings\Personal</personal> | |||
<personal-section>OCA\Accessibility\Settings\PersonalSection</personal-section> | |||
</settings> | |||
</info> |
@@ -0,0 +1,28 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @author John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
return [ | |||
'routes' => [ | |||
['name' => 'accessibility#getCss', 'url' => '/css/user.css', 'verb' => 'GET'], | |||
], | |||
]; |
@@ -0,0 +1,14 @@ | |||
// Revert lighten/darken | |||
@function nc-darken($color, $value) { | |||
@return lighten($color, $value); | |||
} | |||
@function nc-lighten($color, $value) { | |||
@return darken($color, $value); | |||
} | |||
// SCSS variables | |||
$color-main-text: #d8d8d8; | |||
$color-main-background: #181818; | |||
$color-loading-light: #777; | |||
$color-loading-dark: #ccc; |
@@ -0,0 +1,15 @@ | |||
@font-face { | |||
font-family: 'OpenDyslexic'; | |||
font-style: normal; | |||
font-weight: 300; | |||
src: url('../fonts/OpenDyslexic-Regular.woff') format('woff'); | |||
} | |||
@font-face { | |||
font-family: 'OpenDyslexic'; | |||
font-style: normal; | |||
font-weight: 600; | |||
src: url('../fonts/OpenDyslexic-Bold.woff') format('woff'); | |||
} | |||
$font-face: OpenDyslexic, 'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif; |
@@ -0,0 +1,39 @@ | |||
.preview-list { | |||
display: flex; | |||
} | |||
.preview { | |||
display: flex; | |||
flex-direction: column; | |||
width: 300px; | |||
border: 1px solid var(--color-border); | |||
padding: 10px; | |||
border-radius: var(--border-radius); | |||
transition: all 200ms ease-in-out; | |||
filter: drop-shadow(0 1px 2px var(--color-box-shadow)); | |||
background-color: var(--color-main-background); | |||
opacity: 0.9; | |||
&:not(:last-child) { | |||
margin-right: 20px; | |||
} | |||
&, | |||
* { | |||
cursor: pointer; | |||
user-select: none; | |||
} | |||
&:hover, | |||
&.selected { | |||
background-color: var(--color-background-dark); | |||
filter: drop-shadow(0 1px 4px var(--color-box-shadow)); | |||
opacity: 1; | |||
} | |||
.preview-image { | |||
width: 100%; | |||
height: 150px; | |||
background-position: center; | |||
background-size: cover; | |||
background-repeat: no-repeat; | |||
} | |||
p { | |||
text-align: justify; | |||
} | |||
} |
@@ -0,0 +1,76 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
version="1.1" | |||
id="svg2" | |||
width="16" | |||
height="16" | |||
viewBox="0 0 16 16" | |||
sodipodi:docname="app-dark.svg" | |||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"> | |||
<metadata | |||
id="metadata8"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
<dc:title></dc:title> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<defs | |||
id="defs6" /> | |||
<sodipodi:namedview | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1" | |||
objecttolerance="10" | |||
gridtolerance="10" | |||
guidetolerance="10" | |||
inkscape:pageopacity="0" | |||
inkscape:pageshadow="2" | |||
inkscape:window-width="1880" | |||
inkscape:window-height="993" | |||
id="namedview4" | |||
showgrid="false" | |||
showguides="true" | |||
inkscape:guide-bbox="true" | |||
inkscape:zoom="36.460193" | |||
inkscape:cx="8.4752826" | |||
inkscape:cy="18.273624" | |||
inkscape:window-x="20" | |||
inkscape:window-y="67" | |||
inkscape:window-maximized="0" | |||
inkscape:current-layer="g848" | |||
fit-margin-top="0" | |||
fit-margin-left="0" | |||
fit-margin-right="0" | |||
fit-margin-bottom="0" /> | |||
<g | |||
id="g848" | |||
transform="matrix(1.1307959,0,0,1.0801738,-1.0463882,-0.84269722)" | |||
style="stroke-width:0.90481776;fill:#000000"> | |||
<circle | |||
r="1.9587879" | |||
cy="2.8315151" | |||
cx="7.990303" | |||
id="path844" | |||
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.90481776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill" /> | |||
<path | |||
sodipodi:nodetypes="scsssscsccccczzcccccssssccsscs" | |||
inkscape:connector-curvature="0" | |||
id="path843" | |||
d="m 2.3519709,4.2557871 c -0.3126291,0 -0.4819578,0.1287194 -0.5322266,0.4028321 -0.053173,0.2899914 0.1062609,0.5159057 0.4370117,0.6274414 1.420521,0.4790277 2.4256503,0.6675279 3.8410483,0.9800416 0.327839,0.072385 0.6900295,0.2893751 0.6520998,1.0948483 C 6.6985575,8.451345 6.6372144,9.7041167 6.2631031,11.323353 6.0397526,12.290062 5.6782112,13.622766 5.4305838,14.3922 5.3416728,14.668443 5.281658,14.922355 5.281658,15.031849 c 0,0.08257 0.053443,0.249642 0.097656,0.307617 0.023823,0.03125 0.075039,0.07397 0.1147462,0.09522 0.062879,0.03361 0.096262,0.03787 0.2612304,0.03663 0.3361373,-0.0026 0.4608113,-0.08245 0.6665037,-0.429687 0.4838657,-0.939315 0.7378785,-2.132191 0.9402993,-3.014266 0.092189,-0.517235 0.2624476,-1.66347 0.6710287,-1.66347 0.4085811,0 0.4979093,0.95008 0.6812062,1.687228 0.1832969,0.737148 0.6122738,2.295202 0.7738717,2.704862 0.2137476,0.54186 0.5742238,0.836985 0.8764648,0.717774 0.03316,-0.01301 0.116937,-0.04526 0.187989,-0.0708 0.147435,-0.053 0.186715,-0.07824 0.219726,-0.156249 0.0655,-0.154793 -0.01013,-0.454047 -0.349121,-1.41114 C 9.7721847,11.597192 9.2651806,9.3990255 9.3334308,7.2974743 9.3630343,6.3859259 9.6837054,6.305369 10.075725,6.2075087 c 1.17285,-0.2927798 2.00228,-0.379973 3.387085,-0.8579717 0.468513,-0.1617184 0.727539,-0.2608264 0.727539,-0.5590819 0,-0.2554049 -0.153084,-0.4346541 -0.437011,-0.5102538 -0.116851,-0.031101 -0.318383,-0.028905 -0.632326,0.00243 -1.085189,0.10834 -2.939683,0.5153868 -4.0234365,0.6710819 -0.529944,0.076133 -1.7229392,0.094015 -2.2729489,0 C 5.6763224,4.7574297 4.1363176,4.4147025 2.9061699,4.2997326 2.6560099,4.2763537 2.4068766,4.2557871 2.3519709,4.2557871 Z" | |||
style="fill:#000000;stroke-width:0.9048177" /> | |||
</g> | |||
</svg> |
@@ -0,0 +1,76 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
version="1.1" | |||
id="svg2" | |||
width="16" | |||
height="16" | |||
viewBox="0 0 16 16" | |||
sodipodi:docname="app.svg" | |||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"> | |||
<metadata | |||
id="metadata8"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
<dc:title></dc:title> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<defs | |||
id="defs6" /> | |||
<sodipodi:namedview | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1" | |||
objecttolerance="10" | |||
gridtolerance="10" | |||
guidetolerance="10" | |||
inkscape:pageopacity="0" | |||
inkscape:pageshadow="2" | |||
inkscape:window-width="1880" | |||
inkscape:window-height="993" | |||
id="namedview4" | |||
showgrid="false" | |||
showguides="true" | |||
inkscape:guide-bbox="true" | |||
inkscape:zoom="36.460193" | |||
inkscape:cx="8.4752826" | |||
inkscape:cy="18.273624" | |||
inkscape:window-x="20" | |||
inkscape:window-y="67" | |||
inkscape:window-maximized="0" | |||
inkscape:current-layer="g848" | |||
fit-margin-top="0" | |||
fit-margin-left="0" | |||
fit-margin-right="0" | |||
fit-margin-bottom="0" /> | |||
<g | |||
id="g848" | |||
transform="matrix(1.1307959,0,0,1.0801738,-1.0463882,-0.84269722)" | |||
style="stroke-width:0.90481776;fill:#000000"> | |||
<circle | |||
r="1.9587879" | |||
cy="2.8315151" | |||
cx="7.990303" | |||
id="path844" | |||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.90481776;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill" /> | |||
<path | |||
sodipodi:nodetypes="scsssscsccccczzcccccssssccsscs" | |||
inkscape:connector-curvature="0" | |||
id="path843" | |||
d="m 2.3519709,4.2557871 c -0.3126291,0 -0.4819578,0.1287194 -0.5322266,0.4028321 -0.053173,0.2899914 0.1062609,0.5159057 0.4370117,0.6274414 1.420521,0.4790277 2.4256503,0.6675279 3.8410483,0.9800416 0.327839,0.072385 0.6900295,0.2893751 0.6520998,1.0948483 C 6.6985575,8.451345 6.6372144,9.7041167 6.2631031,11.323353 6.0397526,12.290062 5.6782112,13.622766 5.4305838,14.3922 5.3416728,14.668443 5.281658,14.922355 5.281658,15.031849 c 0,0.08257 0.053443,0.249642 0.097656,0.307617 0.023823,0.03125 0.075039,0.07397 0.1147462,0.09522 0.062879,0.03361 0.096262,0.03787 0.2612304,0.03663 0.3361373,-0.0026 0.4608113,-0.08245 0.6665037,-0.429687 0.4838657,-0.939315 0.7378785,-2.132191 0.9402993,-3.014266 0.092189,-0.517235 0.2624476,-1.66347 0.6710287,-1.66347 0.4085811,0 0.4979093,0.95008 0.6812062,1.687228 0.1832969,0.737148 0.6122738,2.295202 0.7738717,2.704862 0.2137476,0.54186 0.5742238,0.836985 0.8764648,0.717774 0.03316,-0.01301 0.116937,-0.04526 0.187989,-0.0708 0.147435,-0.053 0.186715,-0.07824 0.219726,-0.156249 0.0655,-0.154793 -0.01013,-0.454047 -0.349121,-1.41114 C 9.7721847,11.597192 9.2651806,9.3990255 9.3334308,7.2974743 9.3630343,6.3859259 9.6837054,6.305369 10.075725,6.2075087 c 1.17285,-0.2927798 2.00228,-0.379973 3.387085,-0.8579717 0.468513,-0.1617184 0.727539,-0.2608264 0.727539,-0.5590819 0,-0.2554049 -0.153084,-0.4346541 -0.437011,-0.5102538 -0.116851,-0.031101 -0.318383,-0.028905 -0.632326,0.00243 -1.085189,0.10834 -2.939683,0.5153868 -4.0234365,0.6710819 -0.529944,0.076133 -1.7229392,0.094015 -2.2729489,0 C 5.6763224,4.7574297 4.1363176,4.4147025 2.9061699,4.2997326 2.6560099,4.2763537 2.4068766,4.2557871 2.3519709,4.2557871 Z" | |||
style="fill:#ffffff;stroke-width:0.9048177" /> | |||
</g> | |||
</svg> |
@@ -0,0 +1,83 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @author John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace OCA\Accessibility; | |||
use OCP\IL10N; | |||
use OCP\IURLGenerator; | |||
class AccessibilityProvider { | |||
/** @var string */ | |||
protected $appName; | |||
/** @var IURLGenerator */ | |||
private $urlGenerator; | |||
/** @var IL10N */ | |||
private $l; | |||
/** | |||
* Account constructor. | |||
* | |||
* @param string $appName | |||
* @param IURLGenerator $urlGenerator | |||
* @param IL10N $l | |||
*/ | |||
public function __construct(string $appName, | |||
IURLGenerator $urlGenerator, | |||
IL10N $l) { | |||
$this->appName = $appName; | |||
$this->urlGenerator = $urlGenerator; | |||
$this->l = $l; | |||
} | |||
public function getThemes() { | |||
return array( | |||
[ | |||
'id' => 'highcontrast', | |||
'img' => $this->urlGenerator->imagePath($this->appName, 'theme-highcontrast.jpg'), | |||
'title' => $this->l->t('High Contrast theme'), | |||
'text' => $this->l->t('A high contrast theme to ease your navigation. Visual quality will be reduced but clarity will be increased.') | |||
], [ | |||
'id' => 'dark', | |||
'img' => $this->urlGenerator->imagePath($this->appName, 'theme-dark.jpg'), | |||
'title' => $this->l->t('Dark theme'), | |||
'text' => $this->l->t('A dark theme to ease your eyes by reducing the overall luminosity and brightness of your navigation. This is suitable for people who use computes a lot or in low luminosity spaces.') | |||
] | |||
); | |||
} | |||
public function getFonts() { | |||
return array( | |||
[ | |||
'id' => 'dyslexic', | |||
'img' => $this->urlGenerator->imagePath($this->appName, 'font-opendyslexic.jpg'), | |||
'title' => $this->l->t('Dyslexia font'), | |||
'text' => $this->l->t('OpenDyslexic is a free typeface/font designed to mitigate some of the common reading errors caused by dyslexia. The typeface was created by Abelardo Gonzalez, who released it through an open-source license.') | |||
] | |||
); | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @author John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace OCA\Accessibility\AppInfo; | |||
use OCP\AppFramework\App; | |||
class Application extends App { | |||
/** @var string */ | |||
protected $appName = 'accessibility'; | |||
public function __construct() { | |||
parent::__construct($this->appName); | |||
// Inject the fake css on all pages | |||
\OCP\Util::addStyle('accessibility', 'user', true); | |||
} | |||
} |
@@ -0,0 +1,168 @@ | |||
<?php | |||
declare (strict_types = 1); | |||
/** | |||
* @copyright Copyright (c) 2018 John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace OCA\Accessibility\Controller; | |||
use Leafo\ScssPhp\Compiler; | |||
use Leafo\ScssPhp\Exception\ParserException; | |||
use Leafo\ScssPhp\Formatter\Crunched; | |||
use OCP\AppFramework\Controller; | |||
use OCP\AppFramework\Http; | |||
use OCP\AppFramework\Http\DataDisplayResponse; | |||
use OCP\AppFramework\Utility\ITimeFactory; | |||
use OCP\IConfig; | |||
use OCP\ILogger; | |||
use OCP\IRequest; | |||
use OCP\IURLGenerator; | |||
use OCP\IUserManager; | |||
use OCP\IUserSession; | |||
class AccessibilityController extends Controller { | |||
/** @var string */ | |||
protected $appName; | |||
/** @var string */ | |||
protected $serverRoot; | |||
/** @var IConfig */ | |||
private $config; | |||
/** @var IUserManager */ | |||
private $userManager; | |||
/** @var ILogger */ | |||
private $logger; | |||
/** @var IURLGenerator */ | |||
private $urlGenerator; | |||
/** @var ITimeFactory */ | |||
protected $timeFactory; | |||
/** @var IUserSession */ | |||
private $userSession; | |||
/** | |||
* Account constructor. | |||
* | |||
* @param string $appName | |||
* @param IRequest $request | |||
* @param IConfig $config | |||
* @param IUserManager $userManager | |||
* @param ILogger $logger | |||
* @param IURLGenerator $urlGenerator | |||
* @param ITimeFactory $timeFactory | |||
* @param IUserSession $userSession | |||
*/ | |||
public function __construct(string $appName, | |||
IRequest $request, | |||
IConfig $config, | |||
IUserManager $userManager, | |||
ILogger $logger, | |||
IURLGenerator $urlGenerator, | |||
ITimeFactory $timeFactory, | |||
IUserSession $userSession) { | |||
parent::__construct($appName, $request); | |||
$this->config = $config; | |||
$this->userManager = $userManager; | |||
$this->logger = $logger; | |||
$this->urlGenerator = $urlGenerator; | |||
$this->timeFactory = $timeFactory; | |||
$this->userSession = $userSession; | |||
$this->serverRoot = \OC::$SERVERROOT; | |||
$this->appRoot = \OC_App::getAppPath($this->appName); | |||
} | |||
/** | |||
* @NoAdminRequired | |||
* @NoCSRFRequired | |||
* | |||
* @return DataResponse | |||
*/ | |||
public function getCss(): DataDisplayResponse { | |||
$css = ''; | |||
$imports = ''; | |||
foreach ($this->getUserValues() as $scssFile) { | |||
if ($scssFile !== false) { | |||
$imports .= '@import "' . $scssFile . '";'; | |||
} | |||
} | |||
if ($imports !== '') { | |||
$scss = new Compiler(); | |||
$scss->setImportPaths([ | |||
$this->appRoot . '/css/', | |||
$this->serverRoot . '/core/css/' | |||
]); | |||
// Continue after throw | |||
$scss->setIgnoreErrors(true); | |||
$scss->setFormatter(Crunched::class); | |||
// Compile | |||
try { | |||
$css .= $scss->compile( | |||
$imports . | |||
'@import "variables.scss";' . | |||
'@import "css-variables.scss";' | |||
); | |||
} catch (ParserException $e) { | |||
$this->logger->error($e->getMessage(), ['app' => 'core']); | |||
} | |||
} | |||
// We don't want to override vars with url since path is different | |||
$css = $this->filterOutRule('/--[a-z-:]+url\([^;]+\)/mi', $css); | |||
$response = new DataDisplayResponse($css, Http::STATUS_OK, ['Content-Type' => 'text/css']); | |||
$ttl = 31536000; | |||
$response->addHeader('Cache-Control', 'max-age=' . $ttl . ', immutable'); | |||
$expires = new \DateTime(); | |||
$expires->setTimestamp($this->timeFactory->getTime()); | |||
$expires->add(new \DateInterval('PT' . $ttl . 'S')); | |||
$response->addHeader('Expires', $expires->format(\DateTime::RFC1123)); | |||
$response->addHeader('Pragma', 'cache'); | |||
return $response; | |||
} | |||
private function getUserValues() { | |||
$userTheme = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'accessibility', 'theme', false); | |||
$userFont = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'accessibility', 'font', false); | |||
return [ | |||
'theme' => $userTheme, | |||
'font' => $userFont | |||
]; | |||
} | |||
private function filterOutRule(string $rule, string $css) { | |||
return preg_replace($rule, '', $css); | |||
} | |||
} |
@@ -0,0 +1,113 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @author John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace OCA\Accessibility\Settings; | |||
use OCA\Accessibility\AccessibilityProvider; | |||
use OCP\AppFramework\Http\TemplateResponse; | |||
use OCP\IConfig; | |||
use OCP\IL10N; | |||
use OCP\IURLGenerator; | |||
use OCP\IUserSession; | |||
use OCP\Settings\ISettings; | |||
class Personal implements ISettings { | |||
/** @var string */ | |||
protected $appName; | |||
/** @var IConfig */ | |||
private $config; | |||
/** @var IUserSession */ | |||
private $userSession; | |||
/** @var IL10N */ | |||
private $l; | |||
/** @var IURLGenerator */ | |||
private $urlGenerator; | |||
/** @var AccessibilityProvider */ | |||
private $accessibilityProvider; | |||
/** | |||
* Settings constructor. | |||
* | |||
* @param string $appName | |||
* @param IConfig $config | |||
* @param IUserSession $userSession | |||
* @param IL10N $l | |||
* @param IURLGenerator $urlGenerator | |||
* @param AccessibilityProvider $accessibilityProvider | |||
*/ | |||
public function __construct(string $appName, | |||
IConfig $config, | |||
IUserSession $userSession, | |||
IL10N $l, | |||
IURLGenerator $urlGenerator, | |||
AccessibilityProvider $accessibilityProvider) { | |||
$this->appName = $appName; | |||
$this->config = $config; | |||
$this->userSession = $userSession; | |||
$this->l = $l; | |||
$this->urlGenerator = $urlGenerator; | |||
$this->accessibilityProvider = $accessibilityProvider; | |||
} | |||
/** | |||
* @return TemplateResponse returns the instance with all parameters set, ready to be rendered | |||
* @since 9.1 | |||
*/ | |||
public function getForm() { | |||
$serverData = [ | |||
'themes' => $this->accessibilityProvider->getThemes(), | |||
'fonts' => $this->accessibilityProvider->getFonts(), | |||
'theme' => $this->config->getUserValue($this->userSession->getUser()->getUID(), 'accessibility', 'theme', 'dark'), | |||
'font' => $this->config->getUserValue($this->userSession->getUser()->getUID(), 'accessibility', 'font', false) | |||
]; | |||
return new TemplateResponse('accessibility', 'settings-personal', ['serverData' => $serverData]); | |||
} | |||
/** | |||
* @return string the section ID, e.g. 'sharing' | |||
* @since 9.1 | |||
*/ | |||
public function getSection() { | |||
return 'accessibility'; | |||
} | |||
/** | |||
* @return int whether the form should be rather on the top or bottom of | |||
* the admin section. The forms are arranged in ascending order of the | |||
* priority values. It is required to return a value between 0 and 100. | |||
* | |||
* E.g.: 70 | |||
* @since 9.1 | |||
*/ | |||
public function getPriority() { | |||
return 40; | |||
} | |||
} |
@@ -0,0 +1,94 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @author John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
namespace OCA\Accessibility\Settings; | |||
use OCP\IL10N; | |||
use OCP\IURLGenerator; | |||
use OCP\Settings\IIconSection; | |||
class PersonalSection implements IIconSection { | |||
/** @var IURLGenerator */ | |||
private $urlGenerator; | |||
/** @var IL10N */ | |||
private $l; | |||
/** | |||
* Personal Section constructor. | |||
* | |||
* @param IURLGenerator $urlGenerator | |||
* @param IL10N $l | |||
*/ | |||
public function __construct(IURLGenerator $urlGenerator, | |||
IL10N $l) { | |||
$this->urlGenerator = $urlGenerator; | |||
$this->l = $l; | |||
} | |||
/** | |||
* returns the relative path to an 16*16 icon describing the section. | |||
* e.g. '/core/img/places/files.svg' | |||
* | |||
* @returns string | |||
* @since 13.0.0 | |||
*/ | |||
public function getIcon() { | |||
return $this->urlGenerator->imagePath('accessibility', 'app-dark.svg'); | |||
} | |||
/** | |||
* returns the ID of the section. It is supposed to be a lower case string, | |||
* e.g. 'ldap' | |||
* | |||
* @returns string | |||
* @since 9.1 | |||
*/ | |||
public function getID() { | |||
return 'accessibility'; | |||
} | |||
/** | |||
* returns the translated name as it should be displayed, e.g. 'LDAP / AD | |||
* integration'. Use the L10N service to translate it. | |||
* | |||
* @return string | |||
* @since 9.1 | |||
*/ | |||
public function getName() { | |||
return $this->l->t('Accessibility'); | |||
} | |||
/** | |||
* @return int whether the form should be rather on the top or bottom of | |||
* the settings navigation. The sections are arranged in ascending order of | |||
* the priority values. It is required to return a value between 0 and 99. | |||
* | |||
* E.g.: 70 | |||
* @since 9.1 | |||
*/ | |||
public function getPriority() { | |||
return 15; | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
{ | |||
"name": "accessibility", | |||
"description": "Provides multiple accessibilities options to ease your use of nextcloud", | |||
"version": "1.0.0", | |||
"author": "John Molakvoæ <skjnldsv@protonmail.com>", | |||
"license": "agpl", | |||
"private": true, | |||
"scripts": { | |||
"dev": "webpack --config webpack.dev.js", | |||
"watch": "webpack --progress --watch --config webpack.dev.js", | |||
"build": "webpack --progress --hide-modules --config webpack.prod.js" | |||
}, | |||
"dependencies": { | |||
"@babel/core": "^7.0.0-beta.51", | |||
"@babel/preset-env": "^7.0.0-beta.51", | |||
"vue": "^2.5.16" | |||
}, | |||
"browserslist": [ | |||
"last 2 versions", | |||
"not ie <= 11" | |||
], | |||
"devDependencies": { | |||
"babel-core": "^6.26.3", | |||
"babel-loader": "^8.0.0-beta.3", | |||
"babel-preset-env": "^1.7.0", | |||
"css-loader": "^0.28.11", | |||
"file-loader": "^1.1.11", | |||
"node-sass": "^4.9.0", | |||
"sass-loader": "^7.0.3", | |||
"vue-loader": "^15.2.4", | |||
"vue-template-compiler": "^2.5.16", | |||
"webpack": "^4.12.0", | |||
"webpack-cli": "^3.0.4", | |||
"webpack-merge": "^4.1.2" | |||
} | |||
} |
@@ -0,0 +1,76 @@ | |||
<template> | |||
<div id="accessibility"> | |||
<div id="themes" class="section"> | |||
<h2>{{t('accessibility', 'Themes')}}</h2> | |||
<div class="themes-list preview-list"> | |||
<preview v-for="preview in themes" :preview="preview" | |||
:key="preview.id" :selected="selected.theme" | |||
v-on:select="selectTheme"></preview> | |||
</div> | |||
</div> | |||
<div id="fonts" class="section"> | |||
<h2>{{t('accessibility', 'Fonts')}}</h2> | |||
<div class="fonts-list preview-list"> | |||
<preview v-for="preview in fonts" :preview="preview" | |||
:key="preview.id" :selected="selected.font" | |||
v-on:select="selectFont"></preview> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import preview from './components/itemPreview'; | |||
export default { | |||
name: 'app', | |||
components: { preview }, | |||
beforeMount() { | |||
// importing server data into the app | |||
const serverDataElmt = document.getElementById('serverData'); | |||
if (serverDataElmt !== null) { | |||
this.serverData = JSON.parse( | |||
document.getElementById('serverData').dataset.server | |||
); | |||
} | |||
}, | |||
data() { | |||
return { | |||
serverData: [] | |||
}; | |||
}, | |||
computed: { | |||
themes() { | |||
return this.serverData.themes; | |||
}, | |||
fonts() { | |||
return this.serverData.fonts; | |||
}, | |||
selected() { | |||
return { | |||
theme: this.serverData.theme, | |||
font: this.serverData.font | |||
}; | |||
} | |||
}, | |||
methods: { | |||
selectTheme(id) { | |||
this.selectItem('theme', id); | |||
}, | |||
selectFont(id) { | |||
this.selectItem('font', id); | |||
}, | |||
/** | |||
* Commit a change | |||
* | |||
* @param {string} type type of the change (font or theme) | |||
* @param {string} id the data of the change | |||
*/ | |||
selectItem(type, id) { | |||
this.serverData[type] = id; | |||
console.log(type, id); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,24 @@ | |||
<template> | |||
<div :class="{preview: true, selected: preview.id === selected}" | |||
@click="selectItem"> | |||
<div class="preview-image" :style="{backgroundImage: 'url(' + preview.img + ')'}"></div> | |||
<h3>{{preview.title}}</h3> | |||
<p>{{preview.text}}</p> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'itemPreview', | |||
props: ['preview', 'selected'], | |||
methods: { | |||
selectItem() { | |||
this.$emit( | |||
'select', | |||
// if we clicked the already selected one: disable it | |||
this.preview.id === this.selected ? false : this.preview.id | |||
); | |||
} | |||
} | |||
}; | |||
</script> |
@@ -0,0 +1,11 @@ | |||
import Vue from 'vue'; | |||
import App from './App.vue'; | |||
/* global t */ | |||
// bind to window | |||
Vue.prototype.t = t; | |||
new Vue({ | |||
el: '#accessibility', | |||
render: h => h(App) | |||
}); |
@@ -0,0 +1,29 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @author John Molakvoæ <skjnldsv@protonmail.com> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
* | |||
*/ | |||
script('accessibility', 'accessibility'); | |||
style('accessibility', 'style'); | |||
?> | |||
<span id="serverData" data-server="<?php p(json_encode($_['serverData']));?>"></span> | |||
<span id="accessibility"></span> |
@@ -0,0 +1,46 @@ | |||
const path = require('path'); | |||
const { VueLoaderPlugin } = require(`vue-loader`); | |||
module.exports = { | |||
entry: path.join(__dirname, `src`, `main.js`), | |||
output: { | |||
path: path.resolve(__dirname, './js'), | |||
publicPath: '/js/', | |||
filename: 'accessibility.js' | |||
}, | |||
module: { | |||
rules: [ | |||
{ | |||
test: /\.css$/, | |||
use: ['vue-style-loader', 'css-loader'] | |||
}, | |||
{ | |||
test: /\.scss$/, | |||
use: ['vue-style-loader', 'css-loader', 'sass-loader'] | |||
}, | |||
{ | |||
test: /\.vue$/, | |||
loader: 'vue-loader' | |||
}, | |||
{ | |||
test: /\.js$/, | |||
loader: 'babel-loader', | |||
exclude: /node_modules/ | |||
}, | |||
{ | |||
test: /\.(png|jpg|gif|svg)$/, | |||
loader: 'file-loader', | |||
options: { | |||
name: '[name].[ext]?[hash]' | |||
} | |||
} | |||
] | |||
}, | |||
plugins: [new VueLoaderPlugin()], | |||
resolve: { | |||
alias: { | |||
vue$: 'vue/dist/vue.esm.js' | |||
}, | |||
extensions: ['*', '.js', '.vue', '.json'] | |||
} | |||
}; |
@@ -0,0 +1,12 @@ | |||
const merge = require('webpack-merge'); | |||
const common = require('./webpack.common.js'); | |||
module.exports = merge(common, { | |||
mode: 'development', | |||
devServer: { | |||
historyApiFallback: true, | |||
noInfo: true, | |||
overlay: true | |||
}, | |||
devtool: '#eval-source-map' | |||
}); |
@@ -0,0 +1,7 @@ | |||
const merge = require('webpack-merge'); | |||
const common = require('./webpack.common.js'); | |||
module.exports = merge(common, { | |||
mode: 'production', | |||
devtool: '#source-map' | |||
}); |