Merge branch 'master' of github.com:appwrite/appwrite into team-features
This commit is contained in:
commit
f3c8e57e70
39 changed files with 389 additions and 163 deletions
0
.gitattributes
vendored
Normal file
0
.gitattributes
vendored
Normal file
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Added a new route in Locale API to fetch a list of languages
|
- New route in Locale API to fetch a list of languages
|
||||||
|
- Added option to force HTTPS connection to the Appwrite server (_APP_OPTIONS_FORCE_HTTPS)
|
||||||
- Added Google Fonts to Appwrite for offline availability
|
- Added Google Fonts to Appwrite for offline availability
|
||||||
|
- Added a new route in the Avatars API to get user initials avatar
|
||||||
- Added option to delete team from the console
|
- Added option to delete team from the console
|
||||||
- Added option to view team members from the console
|
- Added option to view team members from the console
|
||||||
- Added option to join a user to any team from the console
|
- Added option to join a user to any team from the console
|
||||||
|
@ -12,6 +14,8 @@
|
||||||
|
|
||||||
- Fixed output of /v1/health/queue/certificates returning wrong data
|
- Fixed output of /v1/health/queue/certificates returning wrong data
|
||||||
- Fixed bug where team members count was wrong in some cases
|
- Fixed bug where team members count was wrong in some cases
|
||||||
|
- Fixed network calculation for uploaded files
|
||||||
|
- Fixed a UI bug preventing float values in numeric fields
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ ENV TZ=Asia/Tel_Aviv \
|
||||||
_APP_HOME=https://appwrite.io \
|
_APP_HOME=https://appwrite.io \
|
||||||
_APP_EDITION=community \
|
_APP_EDITION=community \
|
||||||
_APP_OPTIONS_ABUSE=enabled \
|
_APP_OPTIONS_ABUSE=enabled \
|
||||||
|
_APP_OPTIONS_FORCE_HTTPS=disabled \
|
||||||
_APP_OPENSSL_KEY_V1=your-secret-key \
|
_APP_OPENSSL_KEY_V1=your-secret-key \
|
||||||
_APP_STORAGE_LIMIT=104857600 \
|
_APP_STORAGE_LIMIT=104857600 \
|
||||||
_APP_STORAGE_ANTIVIRUS=enabled \
|
_APP_STORAGE_ANTIVIRUS=enabled \
|
||||||
|
|
10
app/app.php
10
app/app.php
|
@ -82,6 +82,14 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $
|
||||||
* As recommended at:
|
* As recommended at:
|
||||||
* @see https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
* @see https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||||
*/
|
*/
|
||||||
|
if ($request->getServer('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
|
||||||
|
if(Config::getParam('protocol') !== 'https') {
|
||||||
|
return $response->redirect('https://' . Config::getParam('domain').$request->getServer('REQUEST_URI'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->addHeader('Strict-Transport-Security', 'max-age='.(60 * 60 * 24 * 126)); // 126 days
|
||||||
|
}
|
||||||
|
|
||||||
$response
|
$response
|
||||||
->addHeader('Server', 'Appwrite')
|
->addHeader('Server', 'Appwrite')
|
||||||
->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url='.urlencode($request->getServer('REQUEST_URI')))
|
->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url='.urlencode($request->getServer('REQUEST_URI')))
|
||||||
|
@ -241,7 +249,7 @@ $utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage
|
||||||
&& $mode !== APP_MODE_ADMIN
|
&& $mode !== APP_MODE_ADMIN
|
||||||
&& !empty($route->getLabel('sdk.namespace', null))) { // Don't calculate console usage and admin mode
|
&& !empty($route->getLabel('sdk.namespace', null))) { // Don't calculate console usage and admin mode
|
||||||
$usage
|
$usage
|
||||||
->setParam('request', $request->getSize())
|
->setParam('request', $request->getSize() + $usage->getParam('storage'))
|
||||||
->setParam('response', $response->getSize())
|
->setParam('response', $response->getSize())
|
||||||
->trigger()
|
->trigger()
|
||||||
;
|
;
|
||||||
|
|
|
@ -16,6 +16,7 @@ use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
|
||||||
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
||||||
use BaconQrCode\Writer;
|
use BaconQrCode\Writer;
|
||||||
use Utopia\Config\Config;
|
use Utopia\Config\Config;
|
||||||
|
use Utopia\Validator\HexColor;
|
||||||
|
|
||||||
include_once __DIR__ . '/../shared/api.php';
|
include_once __DIR__ . '/../shared/api.php';
|
||||||
|
|
||||||
|
@ -385,7 +386,83 @@ $utopia->get('/v1/avatars/qr')
|
||||||
$response
|
$response
|
||||||
->addHeader('Expires', date('D, d M Y H:i:s', time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
->addHeader('Expires', date('D, d M Y H:i:s', time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||||
->setContentType('image/png')
|
->setContentType('image/png')
|
||||||
->send('', $writer->writeString($text))
|
->send($writer->writeString($text))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$utopia->get('/v1/avatars/initials')
|
||||||
|
->desc('Get User Initials')
|
||||||
|
->param('name', '', function () { return new Text(512); }, 'Full Name. When empty, current user name or email will be used.', true)
|
||||||
|
->param('width', 500, function () { return new Range(0, 2000); }, 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||||
|
->param('height', 500, function () { return new Range(0, 2000); }, 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||||
|
->param('color', '', function () { return new HexColor(); }, 'Changes text color. By default a random color will be picked and stay will persistent to the given name.', true)
|
||||||
|
->param('background', '', function () { return new HexColor(); }, 'Changes background color. By default a random color will be picked and stay will persistent to the given name.', true)
|
||||||
|
->label('scope', 'avatars.read')
|
||||||
|
->label('sdk.platform', [APP_PLATFORM_CLIENT, APP_PLATFORM_SERVER])
|
||||||
|
->label('sdk.namespace', 'avatars')
|
||||||
|
->label('sdk.method', 'getInitials')
|
||||||
|
->label('sdk.methodType', 'location')
|
||||||
|
->label('sdk.description', '/docs/references/avatars/get-initials.md')
|
||||||
|
->action(
|
||||||
|
function ($name, $width, $height, $color, $background) use ($response, $user) {
|
||||||
|
$themes = [
|
||||||
|
['color' => '#27005e', 'background' => '#e1d2f6'], // VIOLET
|
||||||
|
['color' => '#5e2700', 'background' => '#f3d9c6'], // ORANGE
|
||||||
|
['color' => '#006128', 'background' => '#c9f3c6'], // GREEN
|
||||||
|
['color' => '#580061', 'background' => '#f2d1f5'], // FUSCHIA
|
||||||
|
['color' => '#00365d', 'background' => '#c6e1f3'], // BLUE
|
||||||
|
['color' => '#00075c', 'background' => '#d2d5f6'], // INDIGO
|
||||||
|
['color' => '#610038', 'background' => '#f5d1e6'], // PINK
|
||||||
|
['color' => '#386100', 'background' => '#dcf1bd'], // LIME
|
||||||
|
['color' => '#615800', 'background' => '#f1ecba'], // YELLOW
|
||||||
|
['color' => '#610008', 'background' => '#f6d2d5'] // RED
|
||||||
|
];
|
||||||
|
|
||||||
|
$rand = rand(0, count($themes)-1);
|
||||||
|
|
||||||
|
$name = (!empty($name)) ? $name : $user->getAttribute('name', $user->getAttribute('email', ''));
|
||||||
|
$words = explode(' ', strtoupper($name));
|
||||||
|
$initials = null;
|
||||||
|
$code = 0;
|
||||||
|
|
||||||
|
foreach ($words as $key => $w) {
|
||||||
|
$initials .= (isset($w[0])) ? $w[0] : '';
|
||||||
|
$code += (isset($w[0])) ? ord($w[0]) : 0;
|
||||||
|
|
||||||
|
if($key == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$length = count($words);
|
||||||
|
$rand = substr($code,-1);
|
||||||
|
$background = (!empty($background)) ? '#'.$background : $themes[$rand]['background'];
|
||||||
|
$color = (!empty($color)) ? '#'.$color : $themes[$rand]['color'];
|
||||||
|
|
||||||
|
$image = new \Imagick();
|
||||||
|
$draw = new \ImagickDraw();
|
||||||
|
$fontSize = min($width, $height) / 2;
|
||||||
|
|
||||||
|
$draw->setFont(__DIR__."/../../../public/fonts/poppins-v9-latin-600.ttf");
|
||||||
|
$image->setFont(__DIR__."/../../../public/fonts/poppins-v9-latin-600.ttf");
|
||||||
|
|
||||||
|
$draw->setFillColor(new \ImagickPixel($color));
|
||||||
|
$draw->setFontSize($fontSize);
|
||||||
|
|
||||||
|
$draw->setTextAlignment(\Imagick::ALIGN_CENTER);
|
||||||
|
$draw->annotation($width / 1.97, ($height / 2) + ($fontSize / 3), $initials);
|
||||||
|
|
||||||
|
$image->newImage($width, $height, $background);
|
||||||
|
$image->setImageFormat("png");
|
||||||
|
$image->drawImage($draw);
|
||||||
|
|
||||||
|
//$image->setImageCompressionQuality(9 - round(($quality / 100) * 9));
|
||||||
|
|
||||||
|
$response
|
||||||
|
->addHeader('Expires', date('D, d M Y H:i:s', time() + (60 * 60 * 24 * 45)).' GMT') // 45 days cache
|
||||||
|
->setContentType('image/png')
|
||||||
|
->send($image->getImageBlob())
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
);
|
);
|
|
@ -425,6 +425,10 @@ $utopia->delete('/v1/projects/:projectId')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$consoleDB->deleteDocument($project->getAttribute('teamId', null))) {
|
||||||
|
throw new Exception('Failed to remove project team from DB', 500);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$consoleDB->deleteDocument($projectId)) {
|
if (!$consoleDB->deleteDocument($projectId)) {
|
||||||
throw new Exception('Failed to remove project from DB', 500);
|
throw new Exception('Failed to remove project from DB', 500);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console" class="back text-size-small"><i class="icon-left-open"></i> Home</a>
|
<a data-ls-attrs="href=/console" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Home</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span>Your Account</span>
|
<span>Your Account</span>
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<a href="https://en.gravatar.com/gravatars/new/" rel="noopener" class="button margin-bottom-small" target="_blank"><i class="icon-upload"></i> Upload</a>
|
<a href="https://en.gravatar.com/gravatars/new/" rel="noopener" class="button margin-bottom-small link-animation-disabled" target="_blank"><i class="icon-upload"></i> Upload</a>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<header class="clear">
|
<header class="clear">
|
||||||
<a href="/console" class="logo pull-start">
|
<a href="/console" class="logo pull-start link-animation-disabled">
|
||||||
<img src="/images/appwrite.svg" alt="Appwrite Light Logo" class="force-light" />
|
<img src="/images/appwrite.svg" alt="Appwrite Light Logo" class="force-light" />
|
||||||
<img src="/images/appwrite-footer-dark.svg" alt="Appwrite Dark Logo" class="force-dark" />
|
<img src="/images/appwrite-footer-dark.svg" alt="Appwrite Dark Logo" class="force-dark" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -34,10 +34,10 @@
|
||||||
data-failure-param-trigger-events="account.deleteSession">
|
data-failure-param-trigger-events="account.deleteSession">
|
||||||
|
|
||||||
<div class="console-back">
|
<div class="console-back">
|
||||||
<a href="/console">Back to Console <i class="icon-right-open"></i></a>
|
<a href="/console" class="link-return-animation--end">Back to Console <i class="icon-right-open"></i></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="account link pull-end clear">
|
<div class="account link link-animation-disabled pull-end clear">
|
||||||
<img src="" data-ls-attrs="src={{account|gravatar}}" alt="User Avatar" class="avatar margin-start pull-end" />
|
<img src="" data-ls-attrs="src={{account|gravatar}}" alt="User Avatar" class="avatar margin-start pull-end" />
|
||||||
<span class="name pull-end desktops-only" data-ls-bind="{{account.name}}"></span>
|
<span class="name pull-end desktops-only" data-ls-bind="{{account.name}}"></span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,10 +45,10 @@
|
||||||
<div class="console-index drop-list bottom end" data-ls-ui-open="" data-button-text="" data-button-icon="" data-button-selector="[data-toggler]" data-button-class="account-button" data-blur="1" tabindex="1">
|
<div class="console-index drop-list bottom end" data-ls-ui-open="" data-button-text="" data-button-icon="" data-button-selector="[data-toggler]" data-button-class="account-button" data-blur="1" tabindex="1">
|
||||||
<ul class="margin-top-large arrow-end">
|
<ul class="margin-top-large arrow-end">
|
||||||
<li>
|
<li>
|
||||||
<a href="/console/account"><i class="icon-user"></i> Your Account</a>
|
<a href="/console/account" class="link-animation-disabled"><i class="icon-user"></i> Your Account</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="link"><i class="icon-sun-inv force-dark pull-start"></i><i class="icon-moon-inv force-light pull-start"></i> Change Theme
|
<span class="link link-animation-disabled"><i class="icon-sun-inv force-dark pull-start"></i><i class="icon-moon-inv force-light pull-start"></i> Change Theme
|
||||||
<div class="pull-end switch-theme">
|
<div class="pull-end switch-theme">
|
||||||
<button data-general-theme
|
<button data-general-theme
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav class="project-only" data-ls-ui-open="" data-button-class="round icon-btn phones-only tablets-only" data-button-icon="icon-dot-3">
|
<nav class="project-only" data-ls-ui-open="" data-button-class="round icon-btn phones-only tablets-only" data-button-icon="icon-dot-3">
|
||||||
<a class="logo" href="/console"
|
<a class="logo link-animation-disabled" href="/console"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="Logo Link">
|
data-analytics-label="Logo Link">
|
||||||
|
@ -83,7 +83,8 @@
|
||||||
<a data-ls-attrs="href=/console/home?project={{router.params.project}}"
|
<a data-ls-attrs="href=/console/home?project={{router.params.project}}"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="Home Link">
|
data-analytics-label="Home Link"
|
||||||
|
class="link-animation-disabled">
|
||||||
<i class="icon-home"></i>
|
<i class="icon-home"></i>
|
||||||
Home
|
Home
|
||||||
</a>
|
</a>
|
||||||
|
@ -97,7 +98,8 @@
|
||||||
<a data-ls-attrs="href=/console/database?project={{router.params.project}}"
|
<a data-ls-attrs="href=/console/database?project={{router.params.project}}"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="Database Link">
|
data-analytics-label="Database Link"
|
||||||
|
class="link-animation-disabled">
|
||||||
<i class="icon-database"></i>
|
<i class="icon-database"></i>
|
||||||
Database
|
Database
|
||||||
</a>
|
</a>
|
||||||
|
@ -106,7 +108,8 @@
|
||||||
<a data-ls-attrs="href=/console/storage?project={{router.params.project}}"
|
<a data-ls-attrs="href=/console/storage?project={{router.params.project}}"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="Storage Link">
|
data-analytics-label="Storage Link"
|
||||||
|
class="link-animation-disabled">
|
||||||
<i class="icon-folder"></i>
|
<i class="icon-folder"></i>
|
||||||
Storage
|
Storage
|
||||||
</a>
|
</a>
|
||||||
|
@ -115,7 +118,8 @@
|
||||||
<a data-ls-attrs="href=/console/users?project={{router.params.project}}"
|
<a data-ls-attrs="href=/console/users?project={{router.params.project}}"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="Users Link">
|
data-analytics-label="Users Link"
|
||||||
|
class="link-animation-disabled">
|
||||||
<i class="icon-users"></i>
|
<i class="icon-users"></i>
|
||||||
Users
|
Users
|
||||||
</a>
|
</a>
|
||||||
|
@ -129,7 +133,8 @@
|
||||||
<a data-ls-attrs="href=/console/tasks?project={{router.params.project}}"
|
<a data-ls-attrs="href=/console/tasks?project={{router.params.project}}"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="Tasks Link">
|
data-analytics-label="Tasks Link"
|
||||||
|
class="link-animation-disabled">
|
||||||
<i class="icon-clock"></i>
|
<i class="icon-clock"></i>
|
||||||
Tasks
|
Tasks
|
||||||
</a>
|
</a>
|
||||||
|
@ -138,7 +143,8 @@
|
||||||
<a data-ls-attrs="href=/console/webhooks?project={{router.params.project}}"
|
<a data-ls-attrs="href=/console/webhooks?project={{router.params.project}}"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="Webhooks Links">
|
data-analytics-label="Webhooks Links"
|
||||||
|
class="link-animation-disabled">
|
||||||
<i class="icon-link"></i>
|
<i class="icon-link"></i>
|
||||||
Webhooks
|
Webhooks
|
||||||
</a>
|
</a>
|
||||||
|
@ -147,7 +153,8 @@
|
||||||
<a data-ls-attrs="href=/console/keys?project={{router.params.project}}"
|
<a data-ls-attrs="href=/console/keys?project={{router.params.project}}"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="API Keys Link">
|
data-analytics-label="API Keys Link"
|
||||||
|
class="link-animation-disabled">
|
||||||
<i class="icon-key-inv"></i>
|
<i class="icon-key-inv"></i>
|
||||||
API Keys
|
API Keys
|
||||||
</a>
|
</a>
|
||||||
|
@ -160,7 +167,8 @@
|
||||||
<a data-ls-attrs="href=/console/settings?project={{router.params.project}}"
|
<a data-ls-attrs="href=/console/settings?project={{router.params.project}}"
|
||||||
data-analytics-event="click"
|
data-analytics-event="click"
|
||||||
data-analytics-category="console/navigation"
|
data-analytics-category="console/navigation"
|
||||||
data-analytics-label="Settings Link">
|
data-analytics-label="Settings Link"
|
||||||
|
class="link-animation-disabled">
|
||||||
<i class="icon-cog"></i> Settings</a>
|
<i class="icon-cog"></i> Settings</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -12,7 +12,7 @@ $rules = $collection->getAttribute('rules', []);
|
||||||
|
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/database?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Database</a>
|
<a data-ls-attrs="href=/console/database?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Database</a>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ $rules = $collection->getAttribute('rules', []);
|
||||||
<script type="text/html" id="template-validation-numeric">
|
<script type="text/html" id="template-validation-numeric">
|
||||||
<div class="margin-bottom">
|
<div class="margin-bottom">
|
||||||
<label data-ls-attrs="for=rule-default-{{rule.$id}}">Default Value</label>
|
<label data-ls-attrs="for=rule-default-{{rule.$id}}">Default Value</label>
|
||||||
<input name="default" type="number" data-ls-bind="{{rule.default}}" data-cast-to="integer" placeholder="0" />
|
<input name="default" type="number" data-ls-bind="{{rule.default}}" data-cast-to="numeric" placeholder="0" step="any" />
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ $collections = [];
|
||||||
$key = (isset($rule['key'])) ? $rule['key'] : '';
|
$key = (isset($rule['key'])) ? $rule['key'] : '';
|
||||||
$label = (isset($rule['label'])) ? $rule['label'] : '';
|
$label = (isset($rule['label'])) ? $rule['label'] : '';
|
||||||
$type = (isset($rule['type'])) ? $rule['type'] : '';
|
$type = (isset($rule['type'])) ? $rule['type'] : '';
|
||||||
$list = (isset($rule['list'])) ? $rule['list'] : [];
|
$list = (isset($rule['list']) && !empty($list)) ? $rule['list'] : [];
|
||||||
?>
|
?>
|
||||||
<?php foreach($list as $item):
|
<?php foreach($list as $item):
|
||||||
if($item === $collection->getId()) {
|
if($item === $collection->getId()) {
|
||||||
|
@ -51,7 +51,7 @@ $collections = [];
|
||||||
$key = (isset($rule['key'])) ? $rule['key'] : '';
|
$key = (isset($rule['key'])) ? $rule['key'] : '';
|
||||||
$label = (isset($rule['label'])) ? $rule['label'] : '';
|
$label = (isset($rule['label'])) ? $rule['label'] : '';
|
||||||
$type = (isset($rule['type'])) ? $rule['type'] : '';
|
$type = (isset($rule['type'])) ? $rule['type'] : '';
|
||||||
$list = (isset($rule['list'])) ? $rule['list'] : false;
|
$list = (isset($rule['list'])) ? $rule['list'] : [];
|
||||||
$array = (isset($rule['array'])) ? $rule['array'] : false;
|
$array = (isset($rule['array'])) ? $rule['array'] : false;
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ $collections = [];
|
||||||
|
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/database/collection?id={{router.params.collection}}&project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> <?php echo $this->escape($name); ?></a>
|
<a data-ls-attrs="href=/console/database/collection?id={{router.params.collection}}&project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> <?php echo $this->escape($name); ?></a>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Home</a>
|
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Home</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span>Database</span>
|
<span>Database</span>
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
<div data-ls-if="0 != {{project-collections.sum}}">
|
<div data-ls-if="0 != {{project-collections.sum}}">
|
||||||
<ul data-ls-loop="project-collections.collections" data-ls-as="collection" data-ls-append="" class="tiles cell-3 margin-bottom-small" style="visibility: hidden">
|
<ul data-ls-loop="project-collections.collections" data-ls-as="collection" data-ls-append="" class="tiles cell-3 margin-bottom-small" style="visibility: hidden">
|
||||||
<li class="margin-bottom">
|
<li class="margin-bottom">
|
||||||
<a data-ls-attrs="href=/console/database/collection?id={{collection.$id}}&project={{router.params.project}}" class="box">
|
<a data-ls-attrs="href=/console/database/collection?id={{collection.$id}}&project={{router.params.project}}" class="box link-animation-disabled">
|
||||||
<div data-ls-bind="{{collection.name}}" class="text-one-liner margin-bottom text-bold"> </div>
|
<div data-ls-bind="{{collection.name}}" class="text-one-liner margin-bottom text-bold"> </div>
|
||||||
|
|
||||||
<i class="icon-right-open"></i>
|
<i class="icon-right-open"></i>
|
||||||
|
|
|
@ -4,4 +4,4 @@ $required = $this->getParam('required', '');
|
||||||
$namespace = $this->getParam('namespace', '');
|
$namespace = $this->getParam('namespace', '');
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<input name="<?php echo $this->escape($key); ?>" type="number" autocomplete="off" data-ls-bind="{{<?php echo $this->escape($namespace); ?>}}" data-cast-to="integer"<?php if($required): ?> required<?php endif; ?> class="margin-bottom-no" />
|
<input name="<?php echo $this->escape($key); ?>" type="number" autocomplete="off" data-ls-bind="{{<?php echo $this->escape($namespace); ?>}}" data-cast-to="numeric"<?php if($required): ?> required<?php endif; ?> class="margin-bottom-no" step=any />
|
|
@ -33,7 +33,7 @@ $home = $this->getParam('home', '');
|
||||||
|
|
||||||
<ul data-ls-loop="console-projects" data-ls-as="project" data-ls-append="" class="tiles cell-3" style="visibility: hidden">
|
<ul data-ls-loop="console-projects" data-ls-as="project" data-ls-append="" class="tiles cell-3" style="visibility: hidden">
|
||||||
<li class="margin-bottom">
|
<li class="margin-bottom">
|
||||||
<a data-ls-attrs="href=/console/home?project={{project.$id}}" class="box">
|
<a data-ls-attrs="href=/console/home?project={{project.$id}}" class="box link-animation-disabled">
|
||||||
<div data-ls-bind="{{project.name}}" class="text-one-liner margin-bottom-tiny text-bold"> </div>
|
<div data-ls-bind="{{project.name}}" class="text-one-liner margin-bottom-tiny text-bold"> </div>
|
||||||
|
|
||||||
<p data-ls-if="({{project.platforms.length}})" class="text-fade text-size-small" data-ls-bind="{{project.platforms.length}} apps"></p>
|
<p data-ls-if="({{project.platforms.length}})" class="text-fade text-size-small" data-ls-bind="{{project.platforms.length}} apps"></p>
|
||||||
|
|
|
@ -3,7 +3,7 @@ $scopes = $this->getParam('scopes', []);
|
||||||
?>
|
?>
|
||||||
<div class="cover margin-bottom-large">
|
<div class="cover margin-bottom-large">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Home</a>
|
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Home</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span>API Keys</span>
|
<span>API Keys</span>
|
||||||
|
|
|
@ -6,7 +6,7 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
|
||||||
?>
|
?>
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Home</a>
|
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Home</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
|
@ -27,8 +27,10 @@ $customDomainsTarget = $this->getParam('customDomainsTarget', false);
|
||||||
<li data-state="/console/settings?project={{router.params.project}}">
|
<li data-state="/console/settings?project={{router.params.project}}">
|
||||||
<h2>Overview</h2>
|
<h2>Overview</h2>
|
||||||
|
|
||||||
<div class="row responsive">
|
<div class="row responsive margin-top-negative">
|
||||||
<div class="col span-8 margin-bottom">
|
<div class="col span-8 margin-bottom">
|
||||||
|
<label> </label>
|
||||||
|
|
||||||
<div class="box margin-bottom-large">
|
<div class="box margin-bottom-large">
|
||||||
<form
|
<form
|
||||||
data-analytics-event="submit"
|
data-analytics-event="submit"
|
||||||
|
|
|
@ -5,7 +5,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
|
||||||
?>
|
?>
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Home</a>
|
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Home</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span>Storage</span>
|
<span>Storage</span>
|
||||||
|
@ -36,7 +36,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
|
||||||
data-failure="alert"
|
data-failure="alert"
|
||||||
data-failure-param-alert-text="Failed to upload file"
|
data-failure-param-alert-text="Failed to upload file"
|
||||||
data-failure-param-alert-classname="error">
|
data-failure-param-alert-classname="error">
|
||||||
<input type="hidden" name="folderId" id="files-folderId" data-cast-to="int" value="1">
|
<input type="hidden" name="folderId" id="files-folderId" data-cast-to="integer" value="1">
|
||||||
|
|
||||||
<label for="file-read">File</label>
|
<label for="file-read">File</label>
|
||||||
<input type="file" name="file" id="file-file" size="1" required>
|
<input type="file" name="file" id="file-file" size="1" required>
|
||||||
|
@ -141,7 +141,7 @@ $fileLimitHuman = $this->getParam('fileLimitHuman', 0);
|
||||||
<div class="input-copy">
|
<div class="input-copy">
|
||||||
<input data-forms-copy type="text" data-ls-attrs="id=file-id-{{file.$id}}" name="fileId" disabled data-ls-bind="{{file.$id}}" />
|
<input data-forms-copy type="text" data-ls-attrs="id=file-id-{{file.$id}}" name="fileId" disabled data-ls-bind="{{file.$id}}" />
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" data-ls-attrs="id=file-folderId-{{file.$id}}" name="folderId" data-cast-to="int" value="1">
|
<input type="hidden" data-ls-attrs="id=file-folderId-{{file.$id}}" name="folderId" data-cast-to="integer" value="1">
|
||||||
|
|
||||||
<label for="file-read">Read Access (<a data-ls-attrs="href={{env.HOME}}/docs/permissions" target="_blank">Learn more</a>)</label>
|
<label for="file-read">Read Access (<a data-ls-attrs="href={{env.HOME}}/docs/permissions" target="_blank">Learn more</a>)</label>
|
||||||
<input type="hidden" data-ls-attrs="id=file-read-{{file.$id}}" name="read" data-forms-tags data-cast-to="json" data-ls-bind="{{file.$permissions.read}}" placeholder="User ID, Team ID or Role" />
|
<input type="hidden" data-ls-attrs="id=file-read-{{file.$id}}" name="read" data-forms-tags data-cast-to="json" data-ls-bind="{{file.$permissions.read}}" placeholder="User ID, Team ID or Role" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="cover margin-bottom-large">
|
<div class="cover margin-bottom-large">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Home</a>
|
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Home</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span>Tasks</span>
|
<span>Tasks</span>
|
||||||
|
|
|
@ -4,7 +4,7 @@ $providers = $this->getParam('providers', []);
|
||||||
|
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Home</a>
|
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Home</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span>Users</span>
|
<span>Users</span>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/users?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Users</a>
|
<a data-ls-attrs="href=/console/users?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Users</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span data-ls-bind="{{user.name}}"> </span>
|
<span data-ls-bind="{{user.name}}"> </span>
|
||||||
|
|
|
@ -5,7 +5,7 @@ $events = array_keys($this->getParam('events', []));
|
||||||
?>
|
?>
|
||||||
<div class="cover margin-bottom-large">
|
<div class="cover margin-bottom-large">
|
||||||
<h1 class="zone xl margin-bottom-large">
|
<h1 class="zone xl margin-bottom-large">
|
||||||
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small"><i class="icon-left-open"></i> Home</a>
|
<a data-ls-attrs="href=/console/home?project={{router.params.project}}" class="back text-size-small link-return-animation--start"><i class="icon-left-open"></i> Home</a>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<span>Webhooks</span>
|
<span>Webhooks</span>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="logo text-align-center margin-bottom-xl">
|
<div class="logo text-align-center margin-bottom-xl">
|
||||||
<a href="/">
|
<a href="/" class="link-animation-disabled">
|
||||||
<img src="/images/appwrite.svg" alt="Appwrite Light Logo" class="force-light" />
|
<img src="/images/appwrite.svg" alt="Appwrite Light Logo" class="force-light" />
|
||||||
<img src="/images/appwrite-footer-dark.svg" alt="Appwrite Dark Logo" class="force-dark" />
|
<img src="/images/appwrite-footer-dark.svg" alt="Appwrite Dark Logo" class="force-dark" />
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
export PHP_VERSION=$PHP_VERSION
|
|
||||||
|
|
||||||
# Init server settings
|
|
||||||
php /usr/share/nginx/html/app/tasks/migrate.php run
|
php /usr/share/nginx/html/app/tasks/migrate.php run
|
|
@ -66,6 +66,7 @@ services:
|
||||||
#- _APP_ENV=production
|
#- _APP_ENV=production
|
||||||
- _APP_ENV=development
|
- _APP_ENV=development
|
||||||
- _APP_OPTIONS_ABUSE=disabled
|
- _APP_OPTIONS_ABUSE=disabled
|
||||||
|
- _APP_OPTIONS_FORCE_HTTPS=disabled
|
||||||
- _APP_OPENSSL_KEY_V1=your-secret-key
|
- _APP_OPENSSL_KEY_V1=your-secret-key
|
||||||
- _APP_DOMAIN=demo.appwrite.io
|
- _APP_DOMAIN=demo.appwrite.io
|
||||||
- _APP_DOMAIN_TARGET=demo.appwrite.io
|
- _APP_DOMAIN_TARGET=demo.appwrite.io
|
||||||
|
|
3
docs/references/avatars/get-initials.md
Normal file
3
docs/references/avatars/get-initials.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.
|
||||||
|
|
||||||
|
You can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.
|
|
@ -10,7 +10,11 @@ Set your server running environment. By default, the var is set to 'development'
|
||||||
|
|
||||||
### _APP_OPTIONS_ABUSE
|
### _APP_OPTIONS_ABUSE
|
||||||
|
|
||||||
Allows you to disable abuse checks and API rate limiting. By default, set to 'enabled'. To cancel the abuse checking, set to 'disabled'. It is not recommended to disable this check-in a production environment.
|
Allows you to disable abuse checks and API rate limiting. By default, set to 'enabled'. To cancel the abuse checking, set to 'disabled'. It is not recommended to disable this feature in a production environment.
|
||||||
|
|
||||||
|
### _APP_OPTIONS_FORCE_HTTPS
|
||||||
|
|
||||||
|
Allows you to force HTTPS connection to your API. This feature redirects any HTTP call to HTTPS and adds the 'Strict-Transport-Security' header to all HTTP responses. By default, set to 'disabled'. To enable, set to 'enabled'. This feature will work only when your ports are set to default 80 and 443.
|
||||||
|
|
||||||
### _APP_OPENSSL_KEY_V1
|
### _APP_OPENSSL_KEY_V1
|
||||||
|
|
||||||
|
|
15
public/dist/scripts/app-all.js
vendored
15
public/dist/scripts/app-all.js
vendored
|
@ -2511,7 +2511,7 @@ match=text.match(new RegExp(regex,'gi'))
|
||||||
if(!match){return fail}
|
if(!match){return fail}
|
||||||
for(i=0,len=match.length;i<len;i++){if(!process(match[i])){return fail}}
|
for(i=0,len=match.length;i<len;i++){if(!process(match[i])){return fail}}
|
||||||
return(date.getTime()/1000)}
|
return(date.getTime()/1000)}
|
||||||
return{format:format,strtotime:strtotime}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,to){switch(to){case'int':case'integer':value=parseInt(value);break;case'string':value=value.toString();break;case'json':value=(value)?JSON.parse(value):[];break;case'array':value=(value&&value.constructor&&value.constructor===Array)?value:[value];break;case'array-empty':value=[];break;case'bool':case'boolean':value=(value==='false')?false:value;value=!!value;break;}
|
return{format:format,strtotime:strtotime}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,to){switch(to){case'int':case'integer':value=parseInt(value);break;case'numeric':value=Number(value);break;case'string':value=value.toString();break;case'json':value=(value)?JSON.parse(value):[];break;case'array':value=(value&&value.constructor&&value.constructor===Array)?value:[value];break;case'array-empty':value=[];break;case'bool':case'boolean':value=(value==='false')?false:value;value=!!value;break;}
|
||||||
return value;}
|
return value;}
|
||||||
function toJson(element,json){json=json||{};let name=element.getAttribute('name');let type=element.getAttribute('type');let castTo=element.getAttribute('data-cast-to');let ref=json;if(name&&'FORM'!==element.tagName){if('FIELDSET'===element.tagName){if(castTo==='object'){if(json[name]===undefined){json[name]={};}
|
function toJson(element,json){json=json||{};let name=element.getAttribute('name');let type=element.getAttribute('type');let castTo=element.getAttribute('data-cast-to');let ref=json;if(name&&'FORM'!==element.tagName){if('FIELDSET'===element.tagName){if(castTo==='object'){if(json[name]===undefined){json[name]={};}
|
||||||
ref=json[name];}
|
ref=json[name];}
|
||||||
|
@ -2553,15 +2553,10 @@ return k;}
|
||||||
function J(k){k=k.replace(/rn/g,"n");let d="";for(let F=0;F<k.length;F++){let x=k.charCodeAt(F);if(x<128){d+=String.fromCharCode(x);}else{if(x>127&&x<2048){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128);}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128);}}}
|
function J(k){k=k.replace(/rn/g,"n");let d="";for(let F=0;F<k.length;F++){let x=k.charCodeAt(F);if(x<128){d+=String.fromCharCode(x);}else{if(x>127&&x<2048){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128);}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128);}}}
|
||||||
return d;}
|
return d;}
|
||||||
let C=Array();let P,h,E,v,g,Y,X,W,V;let S=7,Q=12,N=17,M=22;let A=5,z=9,y=14,w=20;let o=4,m=11,l=16,j=23;let U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P<C.length;P+=16){h=Y;E=X;v=W;g=V;Y=u(Y,X,W,V,C[P+0],S,3614090360);V=u(V,Y,X,W,C[P+1],Q,3905402710);W=u(W,V,Y,X,C[P+2],N,606105819);X=u(X,W,V,Y,C[P+3],M,3250441966);Y=u(Y,X,W,V,C[P+4],S,4118548399);V=u(V,Y,X,W,C[P+5],Q,1200080426);W=u(W,V,Y,X,C[P+6],N,2821735955);X=u(X,W,V,Y,C[P+7],M,4249261313);Y=u(Y,X,W,V,C[P+8],S,1770035416);V=u(V,Y,X,W,C[P+9],Q,2336552879);W=u(W,V,Y,X,C[P+10],N,4294925233);X=u(X,W,V,Y,C[P+11],M,2304563134);Y=u(Y,X,W,V,C[P+12],S,1804603682);V=u(V,Y,X,W,C[P+13],Q,4254626195);W=u(W,V,Y,X,C[P+14],N,2792965006);X=u(X,W,V,Y,C[P+15],M,1236535329);Y=f(Y,X,W,V,C[P+1],A,4129170786);V=f(V,Y,X,W,C[P+6],z,3225465664);W=f(W,V,Y,X,C[P+11],y,643717713);X=f(X,W,V,Y,C[P+0],w,3921069994);Y=f(Y,X,W,V,C[P+5],A,3593408605);V=f(V,Y,X,W,C[P+10],z,38016083);W=f(W,V,Y,X,C[P+15],y,3634488961);X=f(X,W,V,Y,C[P+4],w,3889429448);Y=f(Y,X,W,V,C[P+9],A,568446438);V=f(V,Y,X,W,C[P+14],z,3275163606);W=f(W,V,Y,X,C[P+3],y,4107603335);X=f(X,W,V,Y,C[P+8],w,1163531501);Y=f(Y,X,W,V,C[P+13],A,2850285829);V=f(V,Y,X,W,C[P+2],z,4243563512);W=f(W,V,Y,X,C[P+7],y,1735328473);X=f(X,W,V,Y,C[P+12],w,2368359562);Y=D(Y,X,W,V,C[P+5],o,4294588738);V=D(V,Y,X,W,C[P+8],m,2272392833);W=D(W,V,Y,X,C[P+11],l,1839030562);X=D(X,W,V,Y,C[P+14],j,4259657740);Y=D(Y,X,W,V,C[P+1],o,2763975236);V=D(V,Y,X,W,C[P+4],m,1272893353);W=D(W,V,Y,X,C[P+7],l,4139469664);X=D(X,W,V,Y,C[P+10],j,3200236656);Y=D(Y,X,W,V,C[P+13],o,681279174);V=D(V,Y,X,W,C[P+0],m,3936430074);W=D(W,V,Y,X,C[P+3],l,3572445317);X=D(X,W,V,Y,C[P+6],j,76029189);Y=D(Y,X,W,V,C[P+9],o,3654602809);V=D(V,Y,X,W,C[P+12],m,3873151461);W=D(W,V,Y,X,C[P+15],l,530742520);X=D(X,W,V,Y,C[P+2],j,3299628645);Y=t(Y,X,W,V,C[P+0],U,4096336452);V=t(V,Y,X,W,C[P+7],T,1126891415);W=t(W,V,Y,X,C[P+14],R,2878612391);X=t(X,W,V,Y,C[P+5],O,4237533241);Y=t(Y,X,W,V,C[P+12],U,1700485571);V=t(V,Y,X,W,C[P+3],T,2399980690);W=t(W,V,Y,X,C[P+10],R,4293915773);X=t(X,W,V,Y,C[P+1],O,2240044497);Y=t(Y,X,W,V,C[P+8],U,1873313359);V=t(V,Y,X,W,C[P+15],T,4264355552);W=t(W,V,Y,X,C[P+6],R,2734768916);X=t(X,W,V,Y,C[P+13],O,1309151649);Y=t(Y,X,W,V,C[P+4],U,4149444226);V=t(V,Y,X,W,C[P+11],T,3174756917);W=t(W,V,Y,X,C[P+2],R,718787259);X=t(X,W,V,Y,C[P+9],O,3951481745);Y=K(Y,h);X=K(X,E);W=K(W,v);V=K(V,g);}
|
let C=Array();let P,h,E,v,g,Y,X,W,V;let S=7,Q=12,N=17,M=22;let A=5,z=9,y=14,w=20;let o=4,m=11,l=16,j=23;let U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P<C.length;P+=16){h=Y;E=X;v=W;g=V;Y=u(Y,X,W,V,C[P+0],S,3614090360);V=u(V,Y,X,W,C[P+1],Q,3905402710);W=u(W,V,Y,X,C[P+2],N,606105819);X=u(X,W,V,Y,C[P+3],M,3250441966);Y=u(Y,X,W,V,C[P+4],S,4118548399);V=u(V,Y,X,W,C[P+5],Q,1200080426);W=u(W,V,Y,X,C[P+6],N,2821735955);X=u(X,W,V,Y,C[P+7],M,4249261313);Y=u(Y,X,W,V,C[P+8],S,1770035416);V=u(V,Y,X,W,C[P+9],Q,2336552879);W=u(W,V,Y,X,C[P+10],N,4294925233);X=u(X,W,V,Y,C[P+11],M,2304563134);Y=u(Y,X,W,V,C[P+12],S,1804603682);V=u(V,Y,X,W,C[P+13],Q,4254626195);W=u(W,V,Y,X,C[P+14],N,2792965006);X=u(X,W,V,Y,C[P+15],M,1236535329);Y=f(Y,X,W,V,C[P+1],A,4129170786);V=f(V,Y,X,W,C[P+6],z,3225465664);W=f(W,V,Y,X,C[P+11],y,643717713);X=f(X,W,V,Y,C[P+0],w,3921069994);Y=f(Y,X,W,V,C[P+5],A,3593408605);V=f(V,Y,X,W,C[P+10],z,38016083);W=f(W,V,Y,X,C[P+15],y,3634488961);X=f(X,W,V,Y,C[P+4],w,3889429448);Y=f(Y,X,W,V,C[P+9],A,568446438);V=f(V,Y,X,W,C[P+14],z,3275163606);W=f(W,V,Y,X,C[P+3],y,4107603335);X=f(X,W,V,Y,C[P+8],w,1163531501);Y=f(Y,X,W,V,C[P+13],A,2850285829);V=f(V,Y,X,W,C[P+2],z,4243563512);W=f(W,V,Y,X,C[P+7],y,1735328473);X=f(X,W,V,Y,C[P+12],w,2368359562);Y=D(Y,X,W,V,C[P+5],o,4294588738);V=D(V,Y,X,W,C[P+8],m,2272392833);W=D(W,V,Y,X,C[P+11],l,1839030562);X=D(X,W,V,Y,C[P+14],j,4259657740);Y=D(Y,X,W,V,C[P+1],o,2763975236);V=D(V,Y,X,W,C[P+4],m,1272893353);W=D(W,V,Y,X,C[P+7],l,4139469664);X=D(X,W,V,Y,C[P+10],j,3200236656);Y=D(Y,X,W,V,C[P+13],o,681279174);V=D(V,Y,X,W,C[P+0],m,3936430074);W=D(W,V,Y,X,C[P+3],l,3572445317);X=D(X,W,V,Y,C[P+6],j,76029189);Y=D(Y,X,W,V,C[P+9],o,3654602809);V=D(V,Y,X,W,C[P+12],m,3873151461);W=D(W,V,Y,X,C[P+15],l,530742520);X=D(X,W,V,Y,C[P+2],j,3299628645);Y=t(Y,X,W,V,C[P+0],U,4096336452);V=t(V,Y,X,W,C[P+7],T,1126891415);W=t(W,V,Y,X,C[P+14],R,2878612391);X=t(X,W,V,Y,C[P+5],O,4237533241);Y=t(Y,X,W,V,C[P+12],U,1700485571);V=t(V,Y,X,W,C[P+3],T,2399980690);W=t(W,V,Y,X,C[P+10],R,4293915773);X=t(X,W,V,Y,C[P+1],O,2240044497);Y=t(Y,X,W,V,C[P+8],U,1873313359);V=t(V,Y,X,W,C[P+15],T,4264355552);W=t(W,V,Y,X,C[P+6],R,2734768916);X=t(X,W,V,Y,C[P+13],O,1309151649);Y=t(Y,X,W,V,C[P+4],U,4149444226);V=t(V,Y,X,W,C[P+11],T,3174756917);W=t(W,V,Y,X,C[P+2],R,718787259);X=t(X,W,V,Y,C[P+9],O,3951481745);Y=K(Y,h);X=K(X,E);W=K(W,v);V=K(V,g);}
|
||||||
let i=B(Y)+B(X)+B(W)+B(V);return i.toLowerCase();};let size=element.dataset["size"]||80;let email=$value.email||$value||"";let name=$value.name||$value||"";name=(typeof name!=='string')?'':name;let theme=name.split("").map(char=>char.charCodeAt(0)).reduce((a,b)=>a+b,0).toString();let themes=[{color:"27005e",background:"e1d2f6"},{color:"5e2700",background:"f3d9c6"},{color:"006128",background:"c9f3c6"},{color:"580061",background:"f2d1f5"},{color:"00365d",background:"c6e1f3"},{color:"00075c",background:"d2d5f6"},{color:"610038",background:"f5d1e6"},{color:"386100",background:"dcf1bd"},{color:"615800",background:"f1ecba"},{color:"610008",background:"f6d2d5"}];name=name.split(" ").map(function(n){if(!isNaN(parseFloat(n))&&isFinite(n)){return"";}
|
let i=B(Y)+B(X)+B(W)+B(V);return i.toLowerCase();};let size=element.dataset["size"]||80;let email=$value.email||$value||"";let name=$value.name||$value||"";name=(typeof name!=='string')?'--':name;let def="/v1/avatars/initials?project=console"+"&name="+
|
||||||
return n[0];}).join("")||"--";let background=themes[theme[theme.length-1]]["background"];let color=themes[theme[theme.length-1]]["color"];let def="https://ui-avatars.com/api/"+
|
encodeURIComponent(name)+"&width="+
|
||||||
encodeURIComponent(name)+"/"+
|
size+"&height="+
|
||||||
size+"/"+
|
size;return def;}).add("selectedCollection",function($value,router){return $value===router.params.collectionId?"selected":"";}).add("selectedDocument",function($value,router){return $value===router.params.documentId?"selected":"";}).add("localeString",function($value){$value=parseInt($value);return!Number.isNaN($value)?$value.toLocaleString():"";}).add("date",function($value,date){return date.format("Y-m-d",$value);}).add("date-time",function($value,date){return date.format("Y-m-d H:i",$value);}).add("date-text",function($value,date){return date.format("d M Y",$value);}).add("ms2hum",function($value){let temp=$value;const years=Math.floor(temp/31536000),days=Math.floor((temp%=31536000)/86400),hours=Math.floor((temp%=86400)/3600),minutes=Math.floor((temp%=3600)/60),seconds=temp%60;if(days||hours||seconds||minutes){return((years?years+"y ":"")+
|
||||||
encodeURIComponent(background)+"/"+
|
|
||||||
encodeURIComponent(color);return("//www.gravatar.com/avatar/"+
|
|
||||||
MD5(email)+".jpg?s="+
|
|
||||||
size+"&d="+
|
|
||||||
encodeURIComponent(def));}).add("selectedCollection",function($value,router){return $value===router.params.collectionId?"selected":"";}).add("selectedDocument",function($value,router){return $value===router.params.documentId?"selected":"";}).add("localeString",function($value){$value=parseInt($value);return!Number.isNaN($value)?$value.toLocaleString():"";}).add("date",function($value,date){return date.format("Y-m-d",$value);}).add("date-time",function($value,date){return date.format("Y-m-d H:i",$value);}).add("date-text",function($value,date){return date.format("d M Y",$value);}).add("ms2hum",function($value){let temp=$value;const years=Math.floor(temp/31536000),days=Math.floor((temp%=31536000)/86400),hours=Math.floor((temp%=86400)/3600),minutes=Math.floor((temp%=3600)/60),seconds=temp%60;if(days||hours||seconds||minutes){return((years?years+"y ":"")+
|
|
||||||
(days?days+"d ":"")+
|
(days?days+"d ":"")+
|
||||||
(hours?hours+"h ":"")+
|
(hours?hours+"h ":"")+
|
||||||
(minutes?minutes+"m ":"")+
|
(minutes?minutes+"m ":"")+
|
||||||
|
|
15
public/dist/scripts/app.js
vendored
15
public/dist/scripts/app.js
vendored
|
@ -225,7 +225,7 @@ match=text.match(new RegExp(regex,'gi'))
|
||||||
if(!match){return fail}
|
if(!match){return fail}
|
||||||
for(i=0,len=match.length;i<len;i++){if(!process(match[i])){return fail}}
|
for(i=0,len=match.length;i<len;i++){if(!process(match[i])){return fail}}
|
||||||
return(date.getTime()/1000)}
|
return(date.getTime()/1000)}
|
||||||
return{format:format,strtotime:strtotime}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,to){switch(to){case'int':case'integer':value=parseInt(value);break;case'string':value=value.toString();break;case'json':value=(value)?JSON.parse(value):[];break;case'array':value=(value&&value.constructor&&value.constructor===Array)?value:[value];break;case'array-empty':value=[];break;case'bool':case'boolean':value=(value==='false')?false:value;value=!!value;break;}
|
return{format:format,strtotime:strtotime}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,to){switch(to){case'int':case'integer':value=parseInt(value);break;case'numeric':value=Number(value);break;case'string':value=value.toString();break;case'json':value=(value)?JSON.parse(value):[];break;case'array':value=(value&&value.constructor&&value.constructor===Array)?value:[value];break;case'array-empty':value=[];break;case'bool':case'boolean':value=(value==='false')?false:value;value=!!value;break;}
|
||||||
return value;}
|
return value;}
|
||||||
function toJson(element,json){json=json||{};let name=element.getAttribute('name');let type=element.getAttribute('type');let castTo=element.getAttribute('data-cast-to');let ref=json;if(name&&'FORM'!==element.tagName){if('FIELDSET'===element.tagName){if(castTo==='object'){if(json[name]===undefined){json[name]={};}
|
function toJson(element,json){json=json||{};let name=element.getAttribute('name');let type=element.getAttribute('type');let castTo=element.getAttribute('data-cast-to');let ref=json;if(name&&'FORM'!==element.tagName){if('FIELDSET'===element.tagName){if(castTo==='object'){if(json[name]===undefined){json[name]={};}
|
||||||
ref=json[name];}
|
ref=json[name];}
|
||||||
|
@ -267,15 +267,10 @@ return k;}
|
||||||
function J(k){k=k.replace(/rn/g,"n");let d="";for(let F=0;F<k.length;F++){let x=k.charCodeAt(F);if(x<128){d+=String.fromCharCode(x);}else{if(x>127&&x<2048){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128);}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128);}}}
|
function J(k){k=k.replace(/rn/g,"n");let d="";for(let F=0;F<k.length;F++){let x=k.charCodeAt(F);if(x<128){d+=String.fromCharCode(x);}else{if(x>127&&x<2048){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128);}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128);}}}
|
||||||
return d;}
|
return d;}
|
||||||
let C=Array();let P,h,E,v,g,Y,X,W,V;let S=7,Q=12,N=17,M=22;let A=5,z=9,y=14,w=20;let o=4,m=11,l=16,j=23;let U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P<C.length;P+=16){h=Y;E=X;v=W;g=V;Y=u(Y,X,W,V,C[P+0],S,3614090360);V=u(V,Y,X,W,C[P+1],Q,3905402710);W=u(W,V,Y,X,C[P+2],N,606105819);X=u(X,W,V,Y,C[P+3],M,3250441966);Y=u(Y,X,W,V,C[P+4],S,4118548399);V=u(V,Y,X,W,C[P+5],Q,1200080426);W=u(W,V,Y,X,C[P+6],N,2821735955);X=u(X,W,V,Y,C[P+7],M,4249261313);Y=u(Y,X,W,V,C[P+8],S,1770035416);V=u(V,Y,X,W,C[P+9],Q,2336552879);W=u(W,V,Y,X,C[P+10],N,4294925233);X=u(X,W,V,Y,C[P+11],M,2304563134);Y=u(Y,X,W,V,C[P+12],S,1804603682);V=u(V,Y,X,W,C[P+13],Q,4254626195);W=u(W,V,Y,X,C[P+14],N,2792965006);X=u(X,W,V,Y,C[P+15],M,1236535329);Y=f(Y,X,W,V,C[P+1],A,4129170786);V=f(V,Y,X,W,C[P+6],z,3225465664);W=f(W,V,Y,X,C[P+11],y,643717713);X=f(X,W,V,Y,C[P+0],w,3921069994);Y=f(Y,X,W,V,C[P+5],A,3593408605);V=f(V,Y,X,W,C[P+10],z,38016083);W=f(W,V,Y,X,C[P+15],y,3634488961);X=f(X,W,V,Y,C[P+4],w,3889429448);Y=f(Y,X,W,V,C[P+9],A,568446438);V=f(V,Y,X,W,C[P+14],z,3275163606);W=f(W,V,Y,X,C[P+3],y,4107603335);X=f(X,W,V,Y,C[P+8],w,1163531501);Y=f(Y,X,W,V,C[P+13],A,2850285829);V=f(V,Y,X,W,C[P+2],z,4243563512);W=f(W,V,Y,X,C[P+7],y,1735328473);X=f(X,W,V,Y,C[P+12],w,2368359562);Y=D(Y,X,W,V,C[P+5],o,4294588738);V=D(V,Y,X,W,C[P+8],m,2272392833);W=D(W,V,Y,X,C[P+11],l,1839030562);X=D(X,W,V,Y,C[P+14],j,4259657740);Y=D(Y,X,W,V,C[P+1],o,2763975236);V=D(V,Y,X,W,C[P+4],m,1272893353);W=D(W,V,Y,X,C[P+7],l,4139469664);X=D(X,W,V,Y,C[P+10],j,3200236656);Y=D(Y,X,W,V,C[P+13],o,681279174);V=D(V,Y,X,W,C[P+0],m,3936430074);W=D(W,V,Y,X,C[P+3],l,3572445317);X=D(X,W,V,Y,C[P+6],j,76029189);Y=D(Y,X,W,V,C[P+9],o,3654602809);V=D(V,Y,X,W,C[P+12],m,3873151461);W=D(W,V,Y,X,C[P+15],l,530742520);X=D(X,W,V,Y,C[P+2],j,3299628645);Y=t(Y,X,W,V,C[P+0],U,4096336452);V=t(V,Y,X,W,C[P+7],T,1126891415);W=t(W,V,Y,X,C[P+14],R,2878612391);X=t(X,W,V,Y,C[P+5],O,4237533241);Y=t(Y,X,W,V,C[P+12],U,1700485571);V=t(V,Y,X,W,C[P+3],T,2399980690);W=t(W,V,Y,X,C[P+10],R,4293915773);X=t(X,W,V,Y,C[P+1],O,2240044497);Y=t(Y,X,W,V,C[P+8],U,1873313359);V=t(V,Y,X,W,C[P+15],T,4264355552);W=t(W,V,Y,X,C[P+6],R,2734768916);X=t(X,W,V,Y,C[P+13],O,1309151649);Y=t(Y,X,W,V,C[P+4],U,4149444226);V=t(V,Y,X,W,C[P+11],T,3174756917);W=t(W,V,Y,X,C[P+2],R,718787259);X=t(X,W,V,Y,C[P+9],O,3951481745);Y=K(Y,h);X=K(X,E);W=K(W,v);V=K(V,g);}
|
let C=Array();let P,h,E,v,g,Y,X,W,V;let S=7,Q=12,N=17,M=22;let A=5,z=9,y=14,w=20;let o=4,m=11,l=16,j=23;let U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P<C.length;P+=16){h=Y;E=X;v=W;g=V;Y=u(Y,X,W,V,C[P+0],S,3614090360);V=u(V,Y,X,W,C[P+1],Q,3905402710);W=u(W,V,Y,X,C[P+2],N,606105819);X=u(X,W,V,Y,C[P+3],M,3250441966);Y=u(Y,X,W,V,C[P+4],S,4118548399);V=u(V,Y,X,W,C[P+5],Q,1200080426);W=u(W,V,Y,X,C[P+6],N,2821735955);X=u(X,W,V,Y,C[P+7],M,4249261313);Y=u(Y,X,W,V,C[P+8],S,1770035416);V=u(V,Y,X,W,C[P+9],Q,2336552879);W=u(W,V,Y,X,C[P+10],N,4294925233);X=u(X,W,V,Y,C[P+11],M,2304563134);Y=u(Y,X,W,V,C[P+12],S,1804603682);V=u(V,Y,X,W,C[P+13],Q,4254626195);W=u(W,V,Y,X,C[P+14],N,2792965006);X=u(X,W,V,Y,C[P+15],M,1236535329);Y=f(Y,X,W,V,C[P+1],A,4129170786);V=f(V,Y,X,W,C[P+6],z,3225465664);W=f(W,V,Y,X,C[P+11],y,643717713);X=f(X,W,V,Y,C[P+0],w,3921069994);Y=f(Y,X,W,V,C[P+5],A,3593408605);V=f(V,Y,X,W,C[P+10],z,38016083);W=f(W,V,Y,X,C[P+15],y,3634488961);X=f(X,W,V,Y,C[P+4],w,3889429448);Y=f(Y,X,W,V,C[P+9],A,568446438);V=f(V,Y,X,W,C[P+14],z,3275163606);W=f(W,V,Y,X,C[P+3],y,4107603335);X=f(X,W,V,Y,C[P+8],w,1163531501);Y=f(Y,X,W,V,C[P+13],A,2850285829);V=f(V,Y,X,W,C[P+2],z,4243563512);W=f(W,V,Y,X,C[P+7],y,1735328473);X=f(X,W,V,Y,C[P+12],w,2368359562);Y=D(Y,X,W,V,C[P+5],o,4294588738);V=D(V,Y,X,W,C[P+8],m,2272392833);W=D(W,V,Y,X,C[P+11],l,1839030562);X=D(X,W,V,Y,C[P+14],j,4259657740);Y=D(Y,X,W,V,C[P+1],o,2763975236);V=D(V,Y,X,W,C[P+4],m,1272893353);W=D(W,V,Y,X,C[P+7],l,4139469664);X=D(X,W,V,Y,C[P+10],j,3200236656);Y=D(Y,X,W,V,C[P+13],o,681279174);V=D(V,Y,X,W,C[P+0],m,3936430074);W=D(W,V,Y,X,C[P+3],l,3572445317);X=D(X,W,V,Y,C[P+6],j,76029189);Y=D(Y,X,W,V,C[P+9],o,3654602809);V=D(V,Y,X,W,C[P+12],m,3873151461);W=D(W,V,Y,X,C[P+15],l,530742520);X=D(X,W,V,Y,C[P+2],j,3299628645);Y=t(Y,X,W,V,C[P+0],U,4096336452);V=t(V,Y,X,W,C[P+7],T,1126891415);W=t(W,V,Y,X,C[P+14],R,2878612391);X=t(X,W,V,Y,C[P+5],O,4237533241);Y=t(Y,X,W,V,C[P+12],U,1700485571);V=t(V,Y,X,W,C[P+3],T,2399980690);W=t(W,V,Y,X,C[P+10],R,4293915773);X=t(X,W,V,Y,C[P+1],O,2240044497);Y=t(Y,X,W,V,C[P+8],U,1873313359);V=t(V,Y,X,W,C[P+15],T,4264355552);W=t(W,V,Y,X,C[P+6],R,2734768916);X=t(X,W,V,Y,C[P+13],O,1309151649);Y=t(Y,X,W,V,C[P+4],U,4149444226);V=t(V,Y,X,W,C[P+11],T,3174756917);W=t(W,V,Y,X,C[P+2],R,718787259);X=t(X,W,V,Y,C[P+9],O,3951481745);Y=K(Y,h);X=K(X,E);W=K(W,v);V=K(V,g);}
|
||||||
let i=B(Y)+B(X)+B(W)+B(V);return i.toLowerCase();};let size=element.dataset["size"]||80;let email=$value.email||$value||"";let name=$value.name||$value||"";name=(typeof name!=='string')?'':name;let theme=name.split("").map(char=>char.charCodeAt(0)).reduce((a,b)=>a+b,0).toString();let themes=[{color:"27005e",background:"e1d2f6"},{color:"5e2700",background:"f3d9c6"},{color:"006128",background:"c9f3c6"},{color:"580061",background:"f2d1f5"},{color:"00365d",background:"c6e1f3"},{color:"00075c",background:"d2d5f6"},{color:"610038",background:"f5d1e6"},{color:"386100",background:"dcf1bd"},{color:"615800",background:"f1ecba"},{color:"610008",background:"f6d2d5"}];name=name.split(" ").map(function(n){if(!isNaN(parseFloat(n))&&isFinite(n)){return"";}
|
let i=B(Y)+B(X)+B(W)+B(V);return i.toLowerCase();};let size=element.dataset["size"]||80;let email=$value.email||$value||"";let name=$value.name||$value||"";name=(typeof name!=='string')?'--':name;let def="/v1/avatars/initials?project=console"+"&name="+
|
||||||
return n[0];}).join("")||"--";let background=themes[theme[theme.length-1]]["background"];let color=themes[theme[theme.length-1]]["color"];let def="https://ui-avatars.com/api/"+
|
encodeURIComponent(name)+"&width="+
|
||||||
encodeURIComponent(name)+"/"+
|
size+"&height="+
|
||||||
size+"/"+
|
size;return def;}).add("selectedCollection",function($value,router){return $value===router.params.collectionId?"selected":"";}).add("selectedDocument",function($value,router){return $value===router.params.documentId?"selected":"";}).add("localeString",function($value){$value=parseInt($value);return!Number.isNaN($value)?$value.toLocaleString():"";}).add("date",function($value,date){return date.format("Y-m-d",$value);}).add("date-time",function($value,date){return date.format("Y-m-d H:i",$value);}).add("date-text",function($value,date){return date.format("d M Y",$value);}).add("ms2hum",function($value){let temp=$value;const years=Math.floor(temp/31536000),days=Math.floor((temp%=31536000)/86400),hours=Math.floor((temp%=86400)/3600),minutes=Math.floor((temp%=3600)/60),seconds=temp%60;if(days||hours||seconds||minutes){return((years?years+"y ":"")+
|
||||||
encodeURIComponent(background)+"/"+
|
|
||||||
encodeURIComponent(color);return("//www.gravatar.com/avatar/"+
|
|
||||||
MD5(email)+".jpg?s="+
|
|
||||||
size+"&d="+
|
|
||||||
encodeURIComponent(def));}).add("selectedCollection",function($value,router){return $value===router.params.collectionId?"selected":"";}).add("selectedDocument",function($value,router){return $value===router.params.documentId?"selected":"";}).add("localeString",function($value){$value=parseInt($value);return!Number.isNaN($value)?$value.toLocaleString():"";}).add("date",function($value,date){return date.format("Y-m-d",$value);}).add("date-time",function($value,date){return date.format("Y-m-d H:i",$value);}).add("date-text",function($value,date){return date.format("d M Y",$value);}).add("ms2hum",function($value){let temp=$value;const years=Math.floor(temp/31536000),days=Math.floor((temp%=31536000)/86400),hours=Math.floor((temp%=86400)/3600),minutes=Math.floor((temp%=3600)/60),seconds=temp%60;if(days||hours||seconds||minutes){return((years?years+"y ":"")+
|
|
||||||
(days?days+"d ":"")+
|
(days?days+"d ":"")+
|
||||||
(hours?hours+"h ":"")+
|
(hours?hours+"h ":"")+
|
||||||
(minutes?minutes+"m ":"")+
|
(minutes?minutes+"m ":"")+
|
||||||
|
|
2
public/dist/styles/default-ltr.css
vendored
2
public/dist/styles/default-ltr.css
vendored
File diff suppressed because one or more lines are too long
2
public/dist/styles/default-rtl.css
vendored
2
public/dist/styles/default-rtl.css
vendored
File diff suppressed because one or more lines are too long
|
@ -216,59 +216,68 @@ window.ls.filter
|
||||||
let email = $value.email || $value || "";
|
let email = $value.email || $value || "";
|
||||||
let name = $value.name || $value || "";
|
let name = $value.name || $value || "";
|
||||||
|
|
||||||
name = (typeof name !== 'string') ? '' : name;
|
name = (typeof name !== 'string') ? '--' : name;
|
||||||
|
|
||||||
let theme = name
|
// let theme = name
|
||||||
.split("")
|
// .split("")
|
||||||
.map(char => char.charCodeAt(0))
|
// .map(char => char.charCodeAt(0))
|
||||||
.reduce((a, b) => a + b, 0)
|
// .reduce((a, b) => a + b, 0)
|
||||||
.toString();
|
// .toString();
|
||||||
let themes = [
|
// let themes = [
|
||||||
{ color: "27005e", background: "e1d2f6" }, // VIOLET
|
// { color: "27005e", background: "e1d2f6" }, // VIOLET
|
||||||
{ color: "5e2700", background: "f3d9c6" }, // ORANGE
|
// { color: "5e2700", background: "f3d9c6" }, // ORANGE
|
||||||
{ color: "006128", background: "c9f3c6" }, // GREEN
|
// { color: "006128", background: "c9f3c6" }, // GREEN
|
||||||
{ color: "580061", background: "f2d1f5" }, // FUSCHIA
|
// { color: "580061", background: "f2d1f5" }, // FUSCHIA
|
||||||
{ color: "00365d", background: "c6e1f3" }, // BLUE
|
// { color: "00365d", background: "c6e1f3" }, // BLUE
|
||||||
{ color: "00075c", background: "d2d5f6" }, // INDIGO
|
// { color: "00075c", background: "d2d5f6" }, // INDIGO
|
||||||
{ color: "610038", background: "f5d1e6" }, // PINK
|
// { color: "610038", background: "f5d1e6" }, // PINK
|
||||||
{ color: "386100", background: "dcf1bd" }, // LIME
|
// { color: "386100", background: "dcf1bd" }, // LIME
|
||||||
{ color: "615800", background: "f1ecba" }, // YELLOW
|
// { color: "615800", background: "f1ecba" }, // YELLOW
|
||||||
{ color: "610008", background: "f6d2d5" } // RED
|
// { color: "610008", background: "f6d2d5" } // RED
|
||||||
];
|
// ];
|
||||||
|
|
||||||
name =
|
// name =
|
||||||
name
|
// name
|
||||||
.split(" ")
|
// .split(" ")
|
||||||
.map(function(n) {
|
// .map(function(n) {
|
||||||
if (!isNaN(parseFloat(n)) && isFinite(n)) {
|
// if (!isNaN(parseFloat(n)) && isFinite(n)) {
|
||||||
return "";
|
// return "";
|
||||||
}
|
// }
|
||||||
|
|
||||||
return n[0];
|
// return n[0];
|
||||||
})
|
// })
|
||||||
.join("") || "--";
|
// .join("") || "--";
|
||||||
|
|
||||||
let background = themes[theme[theme.length - 1]]["background"];
|
// let background = themes[theme[theme.length - 1]]["background"];
|
||||||
let color = themes[theme[theme.length - 1]]["color"];
|
// let color = themes[theme[theme.length - 1]]["color"];
|
||||||
|
|
||||||
let def =
|
let def =
|
||||||
"https://ui-avatars.com/api/" +
|
"/v1/avatars/initials?project=console"+
|
||||||
|
"&name=" +
|
||||||
encodeURIComponent(name) +
|
encodeURIComponent(name) +
|
||||||
"/" +
|
"&width=" +
|
||||||
size +
|
size +
|
||||||
"/" +
|
"&height=" +
|
||||||
encodeURIComponent(background) +
|
size;
|
||||||
"/" +
|
|
||||||
encodeURIComponent(color);
|
|
||||||
|
|
||||||
return (
|
return def;
|
||||||
"//www.gravatar.com/avatar/" +
|
// let def =
|
||||||
MD5(email) +
|
// "https://ui-avatars.com/api/" +
|
||||||
".jpg?s=" +
|
// encodeURIComponent(name) +
|
||||||
size +
|
// "/" +
|
||||||
"&d=" +
|
// size +
|
||||||
encodeURIComponent(def)
|
// "/" +
|
||||||
);
|
// encodeURIComponent(background) +
|
||||||
|
// "/" +
|
||||||
|
// encodeURIComponent(color);
|
||||||
|
// return (
|
||||||
|
// "//www.gravatar.com/avatar/" +
|
||||||
|
// MD5(email) +
|
||||||
|
// ".jpg?s=" +
|
||||||
|
// size +
|
||||||
|
// "&d=" +
|
||||||
|
// encodeURIComponent(def)
|
||||||
|
// );
|
||||||
})
|
})
|
||||||
.add("selectedCollection", function($value, router) {
|
.add("selectedCollection", function($value, router) {
|
||||||
return $value === router.params.collectionId ? "selected" : "";
|
return $value === router.params.collectionId ? "selected" : "";
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
case 'integer':
|
case 'integer':
|
||||||
value = parseInt(value);
|
value = parseInt(value);
|
||||||
break;
|
break;
|
||||||
|
case 'numeric':
|
||||||
|
value = Number(value);
|
||||||
|
break;
|
||||||
case 'string':
|
case 'string':
|
||||||
value = value.toString();
|
value = value.toString();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -334,9 +334,6 @@ a.box {
|
||||||
}
|
}
|
||||||
|
|
||||||
a.box:hover {
|
a.box:hover {
|
||||||
border-bottom: none;
|
|
||||||
border-right: none;
|
|
||||||
border-left: none;
|
|
||||||
box-shadow: 0 0 1px rgba(0, 0, 0, .2);
|
box-shadow: 0 0 1px rgba(0, 0, 0, .2);
|
||||||
opacity: .7;
|
opacity: .7;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,6 @@ header {
|
||||||
margin: 7px 0;
|
margin: 7px 0;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -35,10 +31,6 @@ header {
|
||||||
|
|
||||||
.account {
|
.account {
|
||||||
.func-margin-start(25px);
|
.func-margin-start(25px);
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
|
|
|
@ -14,6 +14,8 @@ https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clik
|
||||||
box-shadow: 0 2px 4px 0 rgba(50,50,93,.3);
|
box-shadow: 0 2px 4px 0 rgba(50,50,93,.3);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
&:extend(.force-left);
|
||||||
|
&:extend(.force-ltr);
|
||||||
|
|
||||||
* {
|
* {
|
||||||
font-family: 'Source Code Pro', monospace;
|
font-family: 'Source Code Pro', monospace;
|
||||||
|
|
|
@ -36,7 +36,6 @@ button,
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
background: var(--config-color-focus-hover);
|
background: var(--config-color-focus-hover);
|
||||||
border-bottom: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.fly {
|
&.fly {
|
||||||
|
@ -175,10 +174,6 @@ button,
|
||||||
padding: 0;
|
padding: 0;
|
||||||
.func-padding-end(0) !important;
|
.func-padding-end(0) !important;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-bottom: dotted 1px var(--config-color-link);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: inherit;
|
box-shadow: inherit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,10 +130,6 @@
|
||||||
.account {
|
.account {
|
||||||
.func-margin-start(25px);
|
.func-margin-start(25px);
|
||||||
.text-one-liner;
|
.text-one-liner;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.switch-theme {
|
.switch-theme {
|
||||||
|
@ -189,11 +185,6 @@
|
||||||
height: 39px;
|
height: 39px;
|
||||||
padding: 15px 20px;
|
padding: 15px 20px;
|
||||||
display: block;
|
display: block;
|
||||||
border-bottom: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -364,7 +355,6 @@
|
||||||
&:hover,
|
&:hover,
|
||||||
&.selected {
|
&.selected {
|
||||||
color: #e4e4e4;
|
color: #e4e4e4;
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,6 +538,7 @@
|
||||||
|
|
||||||
@media @tablets, @phones {
|
@media @tablets, @phones {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding-bottom: 32%;
|
||||||
float: none;
|
float: none;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,9 @@ html.home {
|
||||||
.logo {
|
.logo {
|
||||||
a {
|
a {
|
||||||
display: block;
|
display: block;
|
||||||
border-bottom: none;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: .8;
|
opacity: .8;
|
||||||
border-bottom: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,12 @@ a, .link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-left: 2px solid transparent;
|
border-left: 2px solid transparent;
|
||||||
border-right: 2px solid transparent;
|
border-right: 2px solid transparent;
|
||||||
border-bottom: solid 1px transparent;
|
transition: 200ms;
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-bottom: dotted 1px var(--config-color-link);
|
transform: translateY(-2px);
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
|
@ -29,11 +30,11 @@ a, .link {
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled:hover {
|
&.disabled:hover {
|
||||||
border-bottom: none;
|
.link.link-animation-disabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
&.tag:hover {
|
&.tag:hover {
|
||||||
border-bottom: none;
|
.link.link-animation-disabled();
|
||||||
opacity: .9;
|
opacity: .9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +43,46 @@ a, .link {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.link-animation-disabled,
|
||||||
|
.link.link-animation-disabled {
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.func-link-return-animation(@pos) {
|
||||||
|
.link.link-animation-disabled();
|
||||||
|
|
||||||
|
& > i {
|
||||||
|
display: inline-block;
|
||||||
|
transition: 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover > i {
|
||||||
|
transform: translateX(@pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@link-return-animation-offset: 2px;
|
||||||
|
|
||||||
|
.link-return-animation--start {
|
||||||
|
.func-link-return-animation(
|
||||||
|
if((@config-start = right),
|
||||||
|
@link-return-animation-offset,
|
||||||
|
-@link-return-animation-offset
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-return-animation--end {
|
||||||
|
.func-link-return-animation(
|
||||||
|
if((@config-start = right),
|
||||||
|
-@link-return-animation-offset,
|
||||||
|
@link-return-animation-offset
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
b, strong {
|
b, strong {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
@ -197,3 +238,11 @@ small {
|
||||||
.icon-dot-3:before {
|
.icon-dot-3:before {
|
||||||
.func-rotate(90deg);
|
.func-rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fix icons vertical alignment
|
||||||
|
i[class^='icon-'], i[class*=' icon-']{
|
||||||
|
&:before {
|
||||||
|
display: inline;
|
||||||
|
line-height: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -411,4 +411,95 @@ trait AvatarsBase
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testGetInitials()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Test for SUCCESS
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_GET, '/avatars/initials', [
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response['headers']['status-code']);
|
||||||
|
$this->assertEquals('image/png; charset=UTF-8', $response['headers']['content-type']);
|
||||||
|
$this->assertNotEmpty($response['body']);
|
||||||
|
|
||||||
|
$response = $this->client->call(Client::METHOD_GET, '/avatars/initials', [
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], [
|
||||||
|
'width' => 200,
|
||||||
|
'height' => 200,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response['headers']['status-code']);
|
||||||
|
$this->assertEquals('image/png; charset=UTF-8', $response['headers']['content-type']);
|
||||||
|
$this->assertNotEmpty($response['body']);
|
||||||
|
|
||||||
|
$response = $this->client->call(Client::METHOD_GET, '/avatars/initials', [
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], [
|
||||||
|
'name' => 'W W',
|
||||||
|
'width' => 200,
|
||||||
|
'height' => 200,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response['headers']['status-code']);
|
||||||
|
$this->assertEquals('image/png; charset=UTF-8', $response['headers']['content-type']);
|
||||||
|
$this->assertNotEmpty($response['body']);
|
||||||
|
|
||||||
|
$response = $this->client->call(Client::METHOD_GET, '/avatars/initials', [
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], [
|
||||||
|
'name' => 'W W',
|
||||||
|
'width' => 200,
|
||||||
|
'height' => 200,
|
||||||
|
'color' => 'ffffff',
|
||||||
|
'background' => '000000',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response['headers']['status-code']);
|
||||||
|
$this->assertEquals('image/png; charset=UTF-8', $response['headers']['content-type']);
|
||||||
|
$this->assertNotEmpty($response['body']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for FAILURE
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_GET, '/avatars/initials', [
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], [
|
||||||
|
'name' => 'W W',
|
||||||
|
'width' => 200000,
|
||||||
|
'height' => 200,
|
||||||
|
'color' => 'ffffff',
|
||||||
|
'background' => '000000',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(400, $response['headers']['status-code']);
|
||||||
|
|
||||||
|
$response = $this->client->call(Client::METHOD_GET, '/avatars/initials', [
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], [
|
||||||
|
'name' => 'W W',
|
||||||
|
'width' => 200,
|
||||||
|
'height' => 200,
|
||||||
|
'color' => 'white',
|
||||||
|
'background' => '000000',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(400, $response['headers']['status-code']);
|
||||||
|
|
||||||
|
$response = $this->client->call(Client::METHOD_GET, '/avatars/initials', [
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], [
|
||||||
|
'name' => 'W W',
|
||||||
|
'width' => 200,
|
||||||
|
'height' => 200,
|
||||||
|
'color' => 'ffffff',
|
||||||
|
'background' => 'black',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(400, $response['headers']['status-code']);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue