mirror of
https://github.com/openvk/openvk
synced 2024-11-11 01:19:53 +03:00
parent
8700ad8179
commit
f9083edfc4
19 changed files with 327 additions and 7 deletions
|
@ -360,5 +360,6 @@ class Club extends RowModel
|
|||
return $this->getRecord()->alert;
|
||||
}
|
||||
|
||||
use Traits\TBackDrops;
|
||||
use Traits\TSubscribable;
|
||||
}
|
||||
|
|
44
Web/Models/Entities/Traits/TBackDrops.php
Normal file
44
Web/Models/Entities/Traits/TBackDrops.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Models\Entities\Traits;
|
||||
|
||||
use openvk\Web\Models\Entities\Photo;
|
||||
use openvk\Web\Models\Repositories\Photos;
|
||||
|
||||
trait TBackDrops {
|
||||
function getBackDropPictureURLs(): ?array
|
||||
{
|
||||
$photo1 = $this->getRecord()->backdrop_1;
|
||||
$photo2 = $this->getRecord()->backdrop_2;
|
||||
if(is_null($photo1) && is_null($photo2))
|
||||
return NULL;
|
||||
|
||||
$photo1obj = $photo2obj = NULL;
|
||||
if(!is_null($photo1))
|
||||
$photo1obj = (new Photos)->get($photo1);
|
||||
if(!is_null($photo2))
|
||||
$photo2obj = (new Photos)->get($photo2);
|
||||
|
||||
if(is_null($photo1obj) && is_null($photo2obj))
|
||||
return NULL;
|
||||
|
||||
return [
|
||||
is_null($photo1obj) ? "" : $photo1obj->getURL(),
|
||||
is_null($photo2obj) ? "" : $photo2obj->getURL(),
|
||||
];
|
||||
}
|
||||
|
||||
function setBackDropPictures(?Photo $first, ?Photo $second): void
|
||||
{
|
||||
if(!is_null($first))
|
||||
$this->stateChanges("backdrop_1", $first->getId());
|
||||
|
||||
if(!is_null($second))
|
||||
$this->stateChanges("backdrop_2", $second->getId());
|
||||
}
|
||||
|
||||
function unsetBackDropPictures(): void
|
||||
{
|
||||
$this->stateChanges("backdrop_1", NULL);
|
||||
$this->stateChanges("backdrop_2", NULL);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ use openvk\Web\Themes\{Themepack, Themepacks};
|
|||
use openvk\Web\Util\DateTime;
|
||||
use openvk\Web\Models\RowModel;
|
||||
use openvk\Web\Models\Entities\{Photo, Message, Correspondence, Gift};
|
||||
use openvk\Web\Models\Repositories\{Users, Clubs, Albums, Gifts, Notifications};
|
||||
use openvk\Web\Models\Repositories\{Photos, Users, Clubs, Albums, Gifts, Notifications};
|
||||
use openvk\Web\Models\Exceptions\InvalidUserNameException;
|
||||
use Nette\Database\Table\ActiveRow;
|
||||
use Chandler\Database\DatabaseConnection;
|
||||
|
@ -1044,5 +1044,6 @@ class User extends RowModel
|
|||
return true;
|
||||
}
|
||||
|
||||
use Traits\TBackDrops;
|
||||
use Traits\TSubscribable;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Presenters;
|
||||
use openvk\Web\Models\Entities\{Club, Photo};
|
||||
use Nette\InvalidStateException;
|
||||
use openvk\Web\Models\Entities\Notifications\ClubModeratorNotification;
|
||||
use openvk\Web\Models\Repositories\{Clubs, Users, Albums, Managers, Topics};
|
||||
use Chandler\Security\Authenticator;
|
||||
|
@ -191,7 +192,7 @@ final class GroupPresenter extends OpenVKPresenter
|
|||
$this->willExecuteWriteAction();
|
||||
|
||||
$club = $this->clubs->get($id);
|
||||
if(!$club->canBeModifiedBy($this->user->identity))
|
||||
if(!$club || !$club->canBeModifiedBy($this->user->identity))
|
||||
$this->notFound();
|
||||
else
|
||||
$this->template->club = $club;
|
||||
|
@ -250,6 +251,45 @@ final class GroupPresenter extends OpenVKPresenter
|
|||
}
|
||||
}
|
||||
|
||||
function renderEditBackdrop(int $id): void
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
$this->willExecuteWriteAction();
|
||||
|
||||
$club = $this->clubs->get($id);
|
||||
if(!$club || !$club->canBeModifiedBy($this->user->identity))
|
||||
$this->notFound();
|
||||
else
|
||||
$this->template->club = $club;
|
||||
|
||||
if($_SERVER["REQUEST_METHOD"] !== "POST")
|
||||
return;
|
||||
|
||||
if($this->postParam("subact") === "remove") {
|
||||
$club->unsetBackDropPictures();
|
||||
$club->save();
|
||||
$this->flashFail("succ", tr("backdrop_succ_rem"), tr("backdrop_succ_desc")); # will exit
|
||||
}
|
||||
|
||||
$pic1 = $pic2 = NULL;
|
||||
try {
|
||||
if($_FILES["backdrop1"]["error"] !== UPLOAD_ERR_NO_FILE)
|
||||
$pic1 = Photo::fastMake($this->user->id, "Profile backdrop (system)", $_FILES["backdrop1"]);
|
||||
|
||||
if($_FILES["backdrop2"]["error"] !== UPLOAD_ERR_NO_FILE)
|
||||
$pic2 = Photo::fastMake($this->user->id, "Profile backdrop (system)", $_FILES["backdrop2"]);
|
||||
} catch(InvalidStateException $e) {
|
||||
$this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media"));
|
||||
}
|
||||
|
||||
if($pic1 == $pic2 && is_null($pic1))
|
||||
$this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media"));
|
||||
|
||||
$club->setBackDropPictures($pic1, $pic2);
|
||||
$club->save();
|
||||
$this->flashFail("succ", tr("backdrop_succ"), tr("backdrop_succ_desc"));
|
||||
}
|
||||
|
||||
function renderStatistics(int $id): void
|
||||
{
|
||||
$this->assertUserLoggedIn();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?php declare(strict_types=1);
|
||||
namespace openvk\Web\Presenters;
|
||||
use Nette\InvalidStateException;
|
||||
use openvk\Web\Util\Sms;
|
||||
use openvk\Web\Themes\Themepacks;
|
||||
use openvk\Web\Models\Entities\{Photo, Post, EmailChangeVerification};
|
||||
|
@ -208,6 +209,30 @@ final class UserPresenter extends OpenVKPresenter
|
|||
$user->setFav_Books(empty($this->postParam("fav_books")) ? NULL : ovk_proc_strtr($this->postParam("fav_books"), 300));
|
||||
$user->setFav_Quote(empty($this->postParam("fav_quote")) ? NULL : ovk_proc_strtr($this->postParam("fav_quote"), 300));
|
||||
$user->setAbout(empty($this->postParam("about")) ? NULL : ovk_proc_strtr($this->postParam("about"), 300));
|
||||
} elseif($_GET["act"] === "backdrop") {
|
||||
if($this->postParam("subact") === "remove") {
|
||||
$user->unsetBackDropPictures();
|
||||
$user->save();
|
||||
$this->flashFail("succ", tr("backdrop_succ_rem"), tr("backdrop_succ_desc")); # will exit
|
||||
}
|
||||
|
||||
$pic1 = $pic2 = NULL;
|
||||
try {
|
||||
if($_FILES["backdrop1"]["error"] !== UPLOAD_ERR_NO_FILE)
|
||||
$pic1 = Photo::fastMake($user->getId(), "Profile backdrop (system)", $_FILES["backdrop1"]);
|
||||
|
||||
if($_FILES["backdrop2"]["error"] !== UPLOAD_ERR_NO_FILE)
|
||||
$pic2 = Photo::fastMake($user->getId(), "Profile backdrop (system)", $_FILES["backdrop2"]);
|
||||
} catch(InvalidStateException $e) {
|
||||
$this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media"));
|
||||
}
|
||||
|
||||
if($pic1 == $pic2 && is_null($pic1))
|
||||
$this->flashFail("err", tr("backdrop_error_title"), tr("backdrop_error_no_media"));
|
||||
|
||||
$user->setBackDropPictures($pic1, $pic2);
|
||||
$user->save();
|
||||
$this->flashFail("succ", tr("backdrop_succ"), tr("backdrop_succ_desc"));
|
||||
} elseif($_GET['act'] === "status") {
|
||||
if(mb_strlen($this->postParam("status")) > 255) {
|
||||
$statusLength = (string) mb_strlen($this->postParam("status"));
|
||||
|
@ -235,7 +260,7 @@ final class UserPresenter extends OpenVKPresenter
|
|||
}
|
||||
|
||||
$this->template->mode = in_array($this->queryParam("act"), [
|
||||
"main", "contacts", "interests", "avatar"
|
||||
"main", "contacts", "interests", "avatar", "backdrop"
|
||||
]) ? $this->queryParam("act")
|
||||
: "main";
|
||||
|
||||
|
|
|
@ -49,6 +49,12 @@
|
|||
<div class="notifications_global_wrap"></div>
|
||||
<div class="dimmer"></div>
|
||||
|
||||
{if isset($backdrops) && !is_null($backdrops)}
|
||||
<div id="backdrop" style="background-image: url('{$backdrops[0]|noescape}'), url('{$backdrops[1]|noescape}');">
|
||||
<div id="backdropDripper"></div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="toTop">
|
||||
⬆ {_to_top}
|
||||
</div>
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
{_main}
|
||||
</a>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<a href="/club{$club->getId()}/backdrop">
|
||||
{_backdrop_short}
|
||||
</a>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<a href="/club{$club->getId()}/followers">
|
||||
{_followers}
|
||||
|
|
63
Web/Presenters/templates/Group/EditBackdrop.xml
Normal file
63
Web/Presenters/templates/Group/EditBackdrop.xml
Normal file
|
@ -0,0 +1,63 @@
|
|||
{extends "../@layout.xml"}
|
||||
{var $backdrops = $club->getBackDropPictureURLs()}
|
||||
|
||||
{block title}{$club->getName()} | {_backdrop}{/block}
|
||||
|
||||
{block header}
|
||||
<a href="{$club->getURL()}">{$club->getName()}</a> » {_backdrop}
|
||||
{/block}
|
||||
|
||||
{block content}
|
||||
<div class="tabs">
|
||||
<div class="tab">
|
||||
<a href="/club{$club->getId()}/edit">
|
||||
{_main}
|
||||
</a>
|
||||
</div>
|
||||
<div id="activetabs" class="tab">
|
||||
<a id="act_tab_a" href="/club{$club->getId()}/backdrop">
|
||||
{_backdrop_short}
|
||||
</a>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<a href="/club{$club->getId()}/followers">
|
||||
{_followers}
|
||||
</a>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<a href="javascript:void(0)">
|
||||
{_statistics}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container_gray">
|
||||
<h4>{_backdrop}</h4>
|
||||
<p>{_backdrop_desc}</p>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div id="backdropEditor">
|
||||
<div id="backdropFilePicker">
|
||||
<input type="file" accept="image/*" name="backdrop1" />
|
||||
<div id="spacer"></div>
|
||||
<input type="file" accept="image/*" name="backdrop2" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<span class="nobold">{_backdrop_warn}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="nobold">{_backdrop_about_adding}</span>
|
||||
</p>
|
||||
<p><br/></p>
|
||||
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<div>
|
||||
<center>
|
||||
<button name="subact" value="save" class="button">{_backdrop_save}</button>
|
||||
<button name="subact" value="remove" class="button">{_backdrop_remove}</button>
|
||||
</center>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{/block}
|
|
@ -23,6 +23,11 @@
|
|||
{_main}
|
||||
</a>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<a href="/club{$club->getId()}/backdrop">
|
||||
{_backdrop_short}
|
||||
</a>
|
||||
</div>
|
||||
<div id="activetabs" class="tab">
|
||||
<a id="act_tab_a" href="/club{$club->getId()}/followers">
|
||||
{_followers}
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
{_main}
|
||||
</a>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<a href="/club{$club->getId()}/backdrop">
|
||||
{_backdrop_short}
|
||||
</a>
|
||||
</div>
|
||||
<div class="tab">
|
||||
<a href="/club{$club->getId()}/followers">
|
||||
{_followers}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{extends "../@layout.xml"}
|
||||
{var $backdrops = $club->getBackDropPictureURLs()}
|
||||
|
||||
{block title}{$club->getName()}{/block}
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
{extends "../@layout.xml"}
|
||||
{if $mode === 'backdrop'}
|
||||
{var $backdrops = $user->getBackDropPictureURLs()}
|
||||
{/if}
|
||||
|
||||
{block title}{_edit_page}{/block}
|
||||
|
||||
{block header}
|
||||
|
@ -6,11 +10,12 @@
|
|||
{/block}
|
||||
|
||||
{block content}
|
||||
|
||||
{var $isMain = $mode === 'main'}
|
||||
{var $isContacts = $mode === 'contacts'}
|
||||
{var $isInterests = $mode === 'interests'}
|
||||
{var $isAvatar = $mode === 'avatar'}
|
||||
{var $isBackDrop = $mode === 'backdrop'}
|
||||
|
||||
<div n:if="$user->hasPendingNumberChange()" class="msg">
|
||||
<b>Подтверждение номера телефона</b><br/>
|
||||
Введите код для подтверждения смены номера: <a href="/edit/verify_phone">ввести код</a>.
|
||||
|
@ -29,6 +34,9 @@
|
|||
<div n:attr="id => ($isAvatar ? 'activetabs' : 'ki')" class="tab">
|
||||
<a n:attr="id => ($isAvatar ? 'act_tab_a' : 'ki')" href="/edit?act=avatar">{_avatar}</a>
|
||||
</div>
|
||||
<div n:attr="id => ($isBackDrop ? 'activetabs' : 'ki')" class="tab">
|
||||
<a n:attr="id => ($isBackDrop ? 'act_tab_a' : 'ki')" href="/edit?act=backdrop">{_backdrop_short}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container_gray">
|
||||
|
@ -326,6 +334,36 @@
|
|||
</table>
|
||||
</form>
|
||||
|
||||
{elseif $isBackDrop}
|
||||
|
||||
<h4>{_backdrop}</h4>
|
||||
<p>{_backdrop_desc}</p>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div id="backdropEditor">
|
||||
<div id="backdropFilePicker">
|
||||
<input type="file" accept="image/*" name="backdrop1" />
|
||||
<div id="spacer"></div>
|
||||
<input type="file" accept="image/*" name="backdrop2" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<span class="nobold">{_backdrop_warn}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="nobold">{_backdrop_about_adding}</span>
|
||||
</p>
|
||||
<p><br/></p>
|
||||
|
||||
<input type="hidden" name="hash" value="{$csrfToken}" />
|
||||
<div>
|
||||
<center>
|
||||
<button name="subact" value="save" class="button">{_backdrop_save}</button>
|
||||
<button name="subact" value="remove" class="button">{_backdrop_remove}</button>
|
||||
</center>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
{extends "../@layout.xml"}
|
||||
|
||||
{if !$user->isBanned()}
|
||||
{var $backdrops = $user->getBackDropPictureURLs()}
|
||||
{/if}
|
||||
|
||||
{block title}{$user->getCanonicalName()}{/block}
|
||||
|
||||
{block headIncludes}
|
||||
|
|
|
@ -187,6 +187,8 @@ routes:
|
|||
club: "club|public|event"
|
||||
- url: "/club{num}/edit"
|
||||
handler: "Group->edit"
|
||||
- url: "/club{num}/backdrop"
|
||||
handler: "Group->editBackdrop"
|
||||
- url: "/club{num}/stats"
|
||||
handler: "Group->statistics"
|
||||
- url: "/club{num}/followers"
|
||||
|
|
|
@ -190,6 +190,54 @@ p {
|
|||
border-top: 1px solid #CCCCCC;
|
||||
}
|
||||
|
||||
#backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: -100;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: center left, center right;
|
||||
pointer-events: none;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
#backdropDripper {
|
||||
width: 800px;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
background-color: #fff;
|
||||
box-shadow: -30px 0px 20px 20px #fff, -50px 0px 20px 20px hsl(0deg 0% 100% / 59%), -70px 0px 20px 20px hsl(0deg 0% 100% / 43%), -90px 0px 20px 20px hsl(0deg 0% 100% / 35%), -110px 0px 20px 20px hsl(0deg 0% 100% / 28%), -130px 0px 20px 20px hsl(0deg 0% 100% / 16%), 30px 0px 20px 20px #fff, 50px 0px 20px 20px hsl(0deg 0% 100% / 59%), 70px 0px 20px 20px hsl(0deg 0% 100% / 43%), 90px 0px 20px 20px hsl(0deg 0% 100% / 35%), 110px 0px 20px 20px hsl(0deg 0% 100% / 28%), 130px 0px 20px 20px hsl(0deg 0% 100% / 16%);
|
||||
}
|
||||
|
||||
#backdropEditor {
|
||||
position: relative;
|
||||
border: 4px inset #cfcfcf;
|
||||
padding: 8px;
|
||||
width: 550px;
|
||||
height: 270px;
|
||||
margin: 8px auto;
|
||||
background-image: url("../img/backdrop-editor.gif");
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
#backdropFilePicker {
|
||||
position: absolute;
|
||||
top: 140px;
|
||||
padding: 0 19px;
|
||||
}
|
||||
|
||||
#backdropFilePicker > input {
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
#backdropFilePicker > #spacer {
|
||||
display: inline-block;
|
||||
width: calc(550px - 16px - 38px - 171px);
|
||||
}
|
||||
|
||||
.page_body {
|
||||
width: 632px;
|
||||
float: right;
|
||||
|
|
BIN
Web/static/img/backdrop-editor.gif
Normal file
BIN
Web/static/img/backdrop-editor.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
7
install/sqls/00035-backdrops.sql
Normal file
7
install/sqls/00035-backdrops.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
ALTER TABLE `profiles`
|
||||
ADD COLUMN `backdrop_1` BIGINT UNSIGNED NULL DEFAULT NULL AFTER `birthday_privacy`,
|
||||
ADD COLUMN `backdrop_2` BIGINT UNSIGNED NULL DEFAULT NULL AFTER `backdrop_1`;
|
||||
|
||||
ALTER TABLE `groups`
|
||||
ADD COLUMN `backdrop_1` BIGINT UNSIGNED NULL DEFAULT NULL AFTER `alert`,
|
||||
ADD COLUMN `backdrop_2` BIGINT UNSIGNED NULL DEFAULT NULL AFTER `backdrop_1`;
|
|
@ -531,6 +531,19 @@
|
|||
|
||||
"end_all_sessions_done" = "All sessions was ended, including mobile apps";
|
||||
|
||||
"backdrop_short" = "Backdrop";
|
||||
"backdrop" = "Page backdrop";
|
||||
"backdrop_desc" = "Вы можете установить два изображения в качестве фона вашей страницы. Они будут отображаться по бокам у тех, кто зайдёт на вашу страницу. С помощью этой возможности вы можете добавить своему профилю больше индивидуальности.";
|
||||
"backdrop_warn" = "You can set two pictures as your profile or group backdrop. They will be displayed on left and right edges of page. You can customize your profile with this feature, but use it responsibly."
|
||||
"backdrop_about_adding" = "You can upload only one picture, although depending on design, the ending result may look ugly. You can also change only one pic: if you already have two images set up and you want to change one - upload only one, the other won't be removed. To remove both images press the button below, you can't remove pictures individually."
|
||||
"backdrop_save" = "Save backdrop picture(s)";
|
||||
"backdrop_remove" = "Remove all backdrop pictures";
|
||||
"backdrop_error_title" = "Error saving backdrop settings";
|
||||
"backdrop_error_no_media" = "Images are corrupted or haven't been uploaded in their entirety";
|
||||
"backdrop_succ" = "Backdrop settings saved";
|
||||
"backdrop_succ_rem" = "Backdrop images have been removed";
|
||||
"backdrop_succ_desc" = "Users will start seeing changes in 5 minutes.";
|
||||
|
||||
/* Two-factor authentication */
|
||||
|
||||
"two_factor_authentication" = "Two-factor authentication";
|
||||
|
|
|
@ -491,6 +491,18 @@
|
|||
"end_all_sessions" = "Сбросить все сессии";
|
||||
"end_all_sessions_description" = "Если вы хотите выйти из $1 со всех устройств, нажмите на кнопку ниже";
|
||||
"end_all_sessions_done" = "Все сессии сброшены, включая мобильные приложения";
|
||||
"backdrop_short" = "Фон";
|
||||
"backdrop" = "Фон страницы";
|
||||
"backdrop_desc" = "Вы можете установить два изображения в качестве фона вашей страницы. Они будут отображаться по бокам у тех, кто зайдёт на вашу страницу. С помощью этой возможности вы можете добавить своему профилю больше индивидуальности.";
|
||||
"backdrop_warn" = "Изображения будут расположены так, как на схеме выше, их высота будет автоматически увеличена чтобы они занимали 100% высоты экрана, посередине будет размытие, заменить фон основного интерфейса OpenVK или добавить аудиозапись нельзя.";
|
||||
"backdrop_about_adding" = "Вы можете установить только 1 изображение (но будет некрасиво), а так же заменить только одно: если у вас уже стоит два, а вы хотите заменить второе - то загружайте только второе, первое сохранится, а чтобы удалить надо нажать на соответствующую кнопку внизу, удалять по одной нельзя.";
|
||||
"backdrop_save" = "Сохранить фон";
|
||||
"backdrop_remove" = "Удалить фон";
|
||||
"backdrop_error_title" = "Не удалось сохранить фон";
|
||||
"backdrop_error_no_media" = "Изображения повреждены или загружены не полностью";
|
||||
"backdrop_succ" = "Фон сохранён";
|
||||
"backdrop_succ_rem" = "Фон удалён";
|
||||
"backdrop_succ_desc" = "Изменения будут заметны другим пользователям через 5 минут.";
|
||||
|
||||
/* Two-factor authentication */
|
||||
|
||||
|
|
Loading…
Reference in a new issue