Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>tags/v14.0.0beta1
# ignore all apps except core ones | # ignore all apps except core ones | ||||
/apps*/* | /apps*/* | ||||
!/apps/accessibility | |||||
!/apps/comments | !/apps/comments | ||||
!/apps/dav | !/apps/dav | ||||
!/apps/files | !/apps/files |
{ | |||||
"presets": [ | |||||
[ | |||||
"env", | |||||
{ | |||||
"targets": { | |||||
"browsers": ["last 2 versions", "not ie <= 11"] | |||||
} | |||||
} | |||||
] | |||||
] | |||||
} |
root = true | |||||
[*] | |||||
charset = utf-8 | |||||
indent_style = tab | |||||
indent_size = 4 | |||||
end_of_line = lf | |||||
insert_final_newline = true | |||||
trim_trailing_whitespace = true |
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'] | |||||
} | |||||
}; |
.DS_Store | |||||
node_modules/ | |||||
dist/ | |||||
npm-debug.log | |||||
yarn-error.log | |||||
# Editor directories and files | |||||
.idea | |||||
*.suo | |||||
*.ntvs* | |||||
*.njsproj | |||||
*.sln |
{ | |||||
"esversion": 6 | |||||
} |
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 | |||||
# 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 | |||||
``` |
<?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(); |
<?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> |
<?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'], | |||||
], | |||||
]; |
// 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; |
@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; |
.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; | |||||
} | |||||
} |
<?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> |
<?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> |
<?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.') | |||||
] | |||||
); | |||||
} | |||||
} |
<?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); | |||||
} | |||||
} |
<?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); | |||||
} | |||||
} |
<?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; | |||||
} | |||||
} |
<?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; | |||||
} | |||||
} |
{ | |||||
"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" | |||||
} | |||||
} |
<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> |
<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> |
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) | |||||
}); |
<?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> |
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'] | |||||
} | |||||
}; |
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' | |||||
}); |
const merge = require('webpack-merge'); | |||||
const common = require('./webpack.common.js'); | |||||
module.exports = merge(common, { | |||||
mode: 'production', | |||||
devtool: '#source-map' | |||||
}); |