diff --git a/Web/Models/Entities/Club.php b/Web/Models/Entities/Club.php
index a5a3027b..db5baa88 100644
--- a/Web/Models/Entities/Club.php
+++ b/Web/Models/Entities/Club.php
@@ -360,5 +360,6 @@ class Club extends RowModel
return $this->getRecord()->alert;
}
+ use Traits\TBackDrops;
use Traits\TSubscribable;
}
diff --git a/Web/Models/Entities/Traits/TBackDrops.php b/Web/Models/Entities/Traits/TBackDrops.php
new file mode 100644
index 00000000..cab67138
--- /dev/null
+++ b/Web/Models/Entities/Traits/TBackDrops.php
@@ -0,0 +1,44 @@
+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);
+ }
+}
\ No newline at end of file
diff --git a/Web/Models/Entities/User.php b/Web/Models/Entities/User.php
index 59cb33ad..31d8f4c8 100644
--- a/Web/Models/Entities/User.php
+++ b/Web/Models/Entities/User.php
@@ -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;
}
diff --git a/Web/Presenters/GroupPresenter.php b/Web/Presenters/GroupPresenter.php
index 00d74c2e..a0b83a59 100644
--- a/Web/Presenters/GroupPresenter.php
+++ b/Web/Presenters/GroupPresenter.php
@@ -1,6 +1,7 @@
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();
diff --git a/Web/Presenters/UserPresenter.php b/Web/Presenters/UserPresenter.php
index 3acabc84..3cf68757 100644
--- a/Web/Presenters/UserPresenter.php
+++ b/Web/Presenters/UserPresenter.php
@@ -1,5 +1,6 @@
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";
diff --git a/Web/Presenters/templates/@layout.xml b/Web/Presenters/templates/@layout.xml
index 9b5b9de1..8cff0bb8 100644
--- a/Web/Presenters/templates/@layout.xml
+++ b/Web/Presenters/templates/@layout.xml
@@ -49,6 +49,12 @@
+ {if isset($backdrops) && !is_null($backdrops)}
+
+ {/if}
+
⬆ {_to_top}
diff --git a/Web/Presenters/templates/Group/Edit.xml b/Web/Presenters/templates/Group/Edit.xml
index 6eb763ee..ce9a8f04 100644
--- a/Web/Presenters/templates/Group/Edit.xml
+++ b/Web/Presenters/templates/Group/Edit.xml
@@ -12,6 +12,11 @@
{_main}
+
+
+
{_followers}
diff --git a/Web/Presenters/templates/Group/View.xml b/Web/Presenters/templates/Group/View.xml
index dc223af1..e09e3f5f 100644
--- a/Web/Presenters/templates/Group/View.xml
+++ b/Web/Presenters/templates/Group/View.xml
@@ -1,4 +1,5 @@
{extends "../@layout.xml"}
+{var $backdrops = $club->getBackDropPictureURLs()}
{block title}{$club->getName()}{/block}
diff --git a/Web/Presenters/templates/User/Edit.xml b/Web/Presenters/templates/User/Edit.xml
index 18703fcf..b74f04b3 100644
--- a/Web/Presenters/templates/User/Edit.xml
+++ b/Web/Presenters/templates/User/Edit.xml
@@ -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'}
-{var $isMain = $mode === 'main'}
-{var $isContacts = $mode === 'contacts'}
-{var $isInterests = $mode === 'interests'}
-{var $isAvatar = $mode === 'avatar'}
Подтверждение номера телефона
Введите код для подтверждения смены номера:
ввести код.
@@ -29,6 +34,9 @@
+
@@ -326,6 +334,36 @@
+ {elseif $isBackDrop}
+
+
{_backdrop}
+
{_backdrop_desc}
+
+
{/if}
diff --git a/Web/Presenters/templates/User/View.xml b/Web/Presenters/templates/User/View.xml
index a0619a16..61acc215 100644
--- a/Web/Presenters/templates/User/View.xml
+++ b/Web/Presenters/templates/User/View.xml
@@ -1,5 +1,9 @@
{extends "../@layout.xml"}
+{if !$user->isBanned()}
+ {var $backdrops = $user->getBackDropPictureURLs()}
+{/if}
+
{block title}{$user->getCanonicalName()}{/block}
{block headIncludes}
diff --git a/Web/routes.yml b/Web/routes.yml
index d3dcbc83..e5639a08 100644
--- a/Web/routes.yml
+++ b/Web/routes.yml
@@ -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"
diff --git a/Web/static/css/style.css b/Web/static/css/style.css
index 7f17adf4..e6796082 100644
--- a/Web/static/css/style.css
+++ b/Web/static/css/style.css
@@ -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;
diff --git a/Web/static/img/backdrop-editor.gif b/Web/static/img/backdrop-editor.gif
new file mode 100644
index 00000000..1b891403
Binary files /dev/null and b/Web/static/img/backdrop-editor.gif differ
diff --git a/install/sqls/00035-backdrops.sql b/install/sqls/00035-backdrops.sql
new file mode 100644
index 00000000..c8014e82
--- /dev/null
+++ b/install/sqls/00035-backdrops.sql
@@ -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`;
diff --git a/locales/en.strings b/locales/en.strings
index 5a2c7e71..0fc7fa97 100644
--- a/locales/en.strings
+++ b/locales/en.strings
@@ -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";
diff --git a/locales/ru.strings b/locales/ru.strings
index 75adf21f..9fa6284a 100644
--- a/locales/ru.strings
+++ b/locales/ru.strings
@@ -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 */