diff --git a/Web/static/css/main.css b/Web/static/css/main.css
index d7cf6284..d01b6bee 100644
--- a/Web/static/css/main.css
+++ b/Web/static/css/main.css
@@ -55,6 +55,10 @@ h1 {
flex-direction: row;
}
+.display_flex_space_between {
+ justify-content: space-between;
+}
+
.layout {
width: 791px;
margin: 0 auto;
@@ -4006,6 +4010,10 @@ hr {
padding: 5px 10px;
}
+#docs_page_wrapper select {
+ width: 150px;
+}
+
.docListViewItem {
max-height: 52px;
height: 38px;
@@ -4068,17 +4076,39 @@ hr {
}
.docListViewItem .doc_volume {
- display: none;
+ display: flex;
align-items: center;
gap: 5px;
+ visibility: hidden;
}
.docListViewItem .doc_volume > div {
width: 20px;
height: 20px;
- background-color: gray;
+ background: url('/assets/packages/static/openvk/img/docs_controls.png?v=3');
}
.docListViewItem:hover .doc_volume {
- display: flex;
+ visibility: visible;
+}
+
+.docListViewItem .doc_volume > div:hover {
+ cursor: pointer;
+ background-position-y: -21px;
+}
+
+.docListViewItem .doc_volume #report_icon {
+ background-position-x: -40px;
+}
+
+.docListViewItem .doc_volume #edit_icon {
+ background-position-x: -20px;
+}
+
+.docListViewItem .doc_volume #add_icon {
+ background-position-x: -60px;
+}
+
+.docListViewItem .doc_volume #mark_icon {
+ background-position-x: -80px;
}
diff --git a/Web/static/img/docs_controls.png b/Web/static/img/docs_controls.png
new file mode 100644
index 00000000..f56b3c85
Binary files /dev/null and b/Web/static/img/docs_controls.png differ
diff --git a/Web/static/js/al_docs.js b/Web/static/js/al_docs.js
index 1aca33cf..e4dd90a8 100644
--- a/Web/static/js/al_docs.js
+++ b/Web/static/js/al_docs.js
@@ -1 +1,160 @@
-u()
+function showDocumentUploadDialog(target = null, append_to_url = null)
+{
+ let file = null
+ const cmsg = new CMessageBox({
+ title: tr("document_uploading_in_general"),
+ body: `
+
${tr("limits")}
+
+ - ${tr('limitations_file_limit_size', window.openvk.docs_max)}.
+ - ${tr('limitations_file_allowed_formats')}: ${window.openvk.docs_allowed.sort(() => Math.random() - 0.59).slice(0, 10).join(', ')}.
+ - ${tr("limitations_file_author_rights")}.
+
+
+
+
+
+
+ `,
+ buttons: [tr('close')],
+ callbacks: [Function.noop],
+ })
+
+ cmsg.getNode().find('.ovk-diag-body').attr('style', "padding:15px;")
+ cmsg.getNode().attr('style', "width: 400px;")
+ cmsg.getNode().find('#upload_btn').on('change', (e) => {
+ file = e.target.files[0]
+ const name = file.name
+ const format = name.split(".")[1]
+ if(window.openvk.docs_allowed.indexOf(format) == -1) {
+ makeError(tr("error_file_invalid_format"))
+ return
+ }
+
+ if(file.size > window.openvk.docs_max * 1024 * 1024) {
+ makeError(tr("error_file_too_big"))
+ return
+ }
+
+ cmsg.close()
+
+ const cmsg_2 = new CMessageBox({
+ title: tr("document_uploading_in_general"),
+ body: `
+
${tr("info_name")}
+
+
+
+
+
+
+
${tr("tags")}
+
+
+
+ `,
+ buttons: [tr('upload_button'), tr('cancel')],
+ callbacks: [async () => {
+ const fd = new FormData
+ fd.append("name", u(`input[name="doc_name"]`).nodes[0].value)
+ fd.append("tags", u(`input[name="doc_tags"]`).nodes[0].value)
+ fd.append("folder", u(`input[name="doc_access"]:checked`).nodes[0].value)
+ fd.append("owner_hidden", u(`input[name="doc_owner"]`).nodes[0].checked ? "on" : "off")
+ fd.append("blob", file)
+ fd.append("ajax", 1)
+ fd.append("hash", window.router.csrf)
+
+ const endpoint_url = `/docs/upload` + (!isNaN(append_to_url) ? "?gid="+append_to_url : '')
+ const fetcher = await fetch(endpoint_url, {
+ method: 'POST',
+ body: fd,
+ })
+ const json = await fetcher.json()
+
+ if(json.success) {
+ window.router.route(location.href)
+ }
+ }, Function.noop],
+ })
+ cmsg_2.getNode().find('.ovk-diag-body').attr('style', "padding:15px;")
+ cmsg_2.getNode().attr('style', "width: 400px;")
+ })
+}
+
+u(document).on('click', '#upload_entry_point', (e) => {
+ showDocumentUploadDialog(null, Number(e.target.dataset.gid))
+})
+
+u(document).on('change', "#docs_page_wrapper select[name='docs_sort']", (e) => {
+ const new_url = new URL(location.href)
+ new_url.searchParams.set('order', e.target.value)
+
+ window.router.route(new_url.href)
+})
+
+u(document).on('click', '.docListViewItem #remove_icon', async (e) => {
+ const target = u(e.target).closest("#remove_icon")
+ const item = target.closest('.docListViewItem')
+ const id = item.nodes[0].dataset.id.split("_")
+
+ target.addClass('lagged')
+ const res = await window.OVKAPI.call('docs.delete', {owner_id: id[0], doc_id: id[1]})
+ target.removeClass('lagged')
+
+ if(res == 1) {
+ target.attr('id', 'add_icon')
+ }
+})
+
+u(document).on('click', '.docListViewItem #add_icon', async (e) => {
+ const target = u(e.target).closest("#add_icon")
+ const item = target.closest('.docListViewItem')
+ const id = item.nodes[0].dataset.id.split("_")
+
+ target.addClass('lagged')
+
+ try {
+ const res = await window.OVKAPI.call('docs.add', {owner_id: id[0], doc_id: id[1], access_key: id[2]})
+ } catch(e) {
+ makeError(tr("error_file_adding_copied"))
+ target.removeClass('lagged')
+ return
+ }
+
+ target.removeClass('lagged')
+ target.attr('id', 'mark_icon')
+})
+
+u(document).on('click', '.docListViewItem #report_icon', (e) => {
+ const target = u(e.target).closest("#report_icon")
+ const item = target.closest('.docListViewItem')
+ const id = item.nodes[0].dataset.id.split("_")
+
+ MessageBox(tr("report_question"), `
+ ${tr("going_to_report_doc")}
+
${tr("report_question_text")}
+
${tr("report_reason")}:
`, [tr("confirm_m"), tr("cancel")], [(function() {
+
+ res = document.querySelector("#uReportMsgInput").value;
+ xhr = new XMLHttpRequest();
+ xhr.open("GET", "/report/" + id[1] + "?reason=" + res + "&type=doc", true);
+ xhr.onload = (function() {
+ if(xhr.responseText.indexOf("reason") === -1)
+ MessageBox(tr("error"), tr("error_sending_report"), ["OK"], [Function.noop]);
+ else
+ MessageBox(tr("action_successfully"), tr("will_be_watched"), ["OK"], [Function.noop]);
+ });
+ xhr.send(null)
+ }),
+
+ Function.noop])
+})
diff --git a/install/sqls/00054-docs.sql b/install/sqls/00054-docs.sql
index 69059b4c..3d2585ff 100644
--- a/install/sqls/00054-docs.sql
+++ b/install/sqls/00054-docs.sql
@@ -1,6 +1,6 @@
CREATE TABLE `documents` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
- `owner` BIGINT(20) UNSIGNED NOT NULL,
+ `owner` BIGINT(20) NOT NULL,
`virtual_id` BIGINT(20) UNSIGNED NOT NULL,
`hash` CHAR(128) NOT NULL,
`owner_hidden` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
diff --git a/locales/ru.strings b/locales/ru.strings
index af30d2ec..ab87f4f8 100644
--- a/locales/ru.strings
+++ b/locales/ru.strings
@@ -682,6 +682,7 @@
"search_for_notes" = "Поиск записок";
"search_for_audios" = "Поиск музыки";
"search_for_audios_playlists" = "Поиск плейлистов";
+"search_for_docs" = "Поиск документов";
"search_button" = "Найти";
"search_placeholder" = "Начните вводить любое имя, название или слово";
"results_zero" = "Ни одного результата";
@@ -1239,6 +1240,7 @@
"going_to_report_user" = "Вы собираетесь пожаловаться на данного пользователя.";
"going_to_report_video" = "Вы собираетесь пожаловаться на данную видеозапись.";
"going_to_report_audio" = "Вы собираетесь пожаловаться на данную аудиозапись.";
+"going_to_report_doc" = "Вы собираетесь пожаловаться на этот документ.";
"going_to_report_post" = "Вы собираетесь пожаловаться на данную запись.";
"going_to_report_comment" = "Вы собираетесь пожаловаться на данный комментарий.";
@@ -2008,6 +2010,7 @@
"s_videos" = "Видео";
"s_audios" = "Аудио";
"s_audios_playlists" = "Плейлисты";
+"s_documents" = "Документы";
"s_by_people" = "по пользователям";
"s_by_groups" = "по группам";
@@ -2017,6 +2020,7 @@
"s_by_apps" = "по приложениям";
"s_by_audios" = "по аудиозаписям";
"s_by_audios_playlists" = "по плейлистам";
+"s_by_documents" = "по документам";
"s_order_by" = "Порядок";
@@ -2039,6 +2043,7 @@
"s_date_after" = "После";
"s_main" = "Основное";
+"s_type" = "Тип";
"s_now_on_site" = "cейчас на сайте";
"s_with_photo" = "с фото";
@@ -2214,6 +2219,7 @@
"document_uploading_in_general" = "Загрузка документа";
"file" = "Файл";
"tags" = "Теги";
+"owner_is_hidden" = "Автор скрыт";
"accessbility" = "Доступность";
"document_type_0" = "Все";
@@ -2245,3 +2251,16 @@
"x_documents_in_tab_zero" = "В этой вкладке $1 документов";
"there_is_no_documents_alright" = "Здесь нет документов.";
+"limitations_file_limit_size" = "Файл не должен превышать $1 МБ";
+"limitations_file_allowed_formats" = "Разрешены следующие типы файлов";
+"limitations_file_author_rights" = "Файл не должен нарушать авторские права и правила сайта";
+"select_file_fp" = "Выбрать файл";
+"error_file_too_big" = "Файл слишком большой.";
+"error_file_invalid_format" = "Формат файла не разрешён.";
+"error_file_adding_copied" = "Не удалось добавить файл; он уже добавлен.";
+
+"private_document" = "Приватный (по ссылке)";
+"public_document" = "Публичный";
+"documents_sort_add" = "По дате добавления";
+"documents_sort_alphabet" = "A-Z/А-Я";
+"documents_sort_size" = "По размеру";