diff --git a/Web/Presenters/templates/components/post/microblogpost.xml b/Web/Presenters/templates/components/post/microblogpost.xml
index ce720b55..a37076b1 100644
--- a/Web/Presenters/templates/components/post/microblogpost.xml
+++ b/Web/Presenters/templates/components/post/microblogpost.xml
@@ -126,7 +126,7 @@
-
+
{if $repostsCount > 0}{$repostsCount}{/if}
diff --git a/Web/Presenters/templates/components/textArea.xml b/Web/Presenters/templates/components/textArea.xml
index 859865ca..e53c1d88 100644
--- a/Web/Presenters/templates/components/textArea.xml
+++ b/Web/Presenters/templates/components/textArea.xml
@@ -114,9 +114,8 @@
setupWallPostInputHandlers({$textAreaId});
});
- u("#post-buttons{$textAreaId} input[name='videos']")["nodes"].at(0).value = ""
- u("#post-buttons{$textAreaId} input[name='photos']")["nodes"].at(0).value = ""
- u("#post-buttons{$textAreaId} input[name='audios']")["nodes"].at(0).value = ""
+ u("#post-buttons{$textAreaId} input[name='horizontal_attachments']")["nodes"].at(0).value = ""
+ u("#post-buttons{$textAreaId} input[name='vertical_attachments']")["nodes"].at(0).value = ""
{if $graffiti}
diff --git a/Web/static/css/dialog.css b/Web/static/css/dialog.css
index c264dbb6..6f940d40 100644
--- a/Web/static/css/dialog.css
+++ b/Web/static/css/dialog.css
@@ -7,6 +7,11 @@ body.dimmed > .dimmer {
opacity: .5;
}
+body.dimmed > .dimmer #absolute_territory {
+ margin: 100px;
+ height: 100%;
+}
+
.ovk-diag-cont {
z-index: 1024;
position: fixed;
diff --git a/Web/static/css/main.css b/Web/static/css/main.css
index a0e37144..680a4a14 100644
--- a/Web/static/css/main.css
+++ b/Web/static/css/main.css
@@ -13,6 +13,10 @@ body {
word-wrap: break-word;
}
+body, .ovk-fullscreen-dimmer {
+ scrollbar-gutter: stable both-edges;
+}
+
.nobold,
nobold {
font-weight: normal;
@@ -41,6 +45,11 @@ h1 {
margin-top: 0;
}
+.display_flex_column {
+ display: flex;
+ flex-direction: column;
+}
+
.layout {
width: 791px;
margin: 0 auto;
@@ -254,6 +263,28 @@ h1 {
width: calc(550px - 16px - 38px - 171px);
}
+.upLeftErrors {
+ position: absolute;
+ display: flex;
+ flex-direction: column;
+ z-index: 1025;
+}
+
+.upLeftErrors .upLeftError {
+ padding: 2px 2px 2px 2px;
+ display: inline-block;
+ border-radius: 0px 0px 5px 0px;
+ font-size: 15px;
+}
+
+.upLeftErrors .upLeftError.upLeftErrorRed {
+ background: #ff7474;
+}
+
+.upLeftErrors .upLeftError.upLeftErrorGreen {
+ background: #74ff92;
+}
+
.page_body {
width: 632px;
float: right;
diff --git a/Web/static/js/al_api.js b/Web/static/js/al_api.js
index 04344415..eb613dc1 100644
--- a/Web/static/js/al_api.js
+++ b/Web/static/js/al_api.js
@@ -34,4 +34,22 @@ window.API = new Proxy(Object.create(null), {
window.API.Types = {};
window.API.Types.Message = (class Message {
-});
\ No newline at end of file
+});
+
+window.OVKAPI = new class {
+ async call(method, params) {
+ if(!method) {
+ return
+ }
+
+ const url = `/method/${method}?auth_mechanism=roaming&${new URLSearchParams(params).toString()}`
+ const res = await fetch(url)
+ const json_response = await res.json()
+
+ if(json_response.response) {
+ return json_response.response
+ } else {
+ throw new Exception(json_response.error_msg)
+ }
+ }
+}
diff --git a/Web/static/js/al_music.js b/Web/static/js/al_music.js
index 7ee1f035..f25518b4 100644
--- a/Web/static/js/al_music.js
+++ b/Web/static/js/al_music.js
@@ -1,13 +1,3 @@
-function fmtTime(time) {
- const mins = String(Math.floor(time / 60)).padStart(2, '0');
- const secs = String(Math.floor(time % 60)).padStart(2, '0');
- return `${ mins}:${ secs}`;
-}
-
-function fastError(message) {
- MessageBox(tr("error"), message, [tr("ok")], [Function.noop])
-}
-
// elapsed это вроде прошедшие, а оставшееся это remaining но ладно уже
function getElapsedTime(fullTime, time) {
let timer = fullTime - time
diff --git a/Web/static/js/al_wall.js b/Web/static/js/al_wall.js
index a8273b21..76ce1750 100644
--- a/Web/static/js/al_wall.js
+++ b/Web/static/js/al_wall.js
@@ -1,35 +1,3 @@
-function humanFileSize(bytes, si) {
- var thresh = si ? 1000 : 1024;
- if(Math.abs(bytes) < thresh) {
- return bytes + ' B';
- }
- var units = si
- ? ['kB','MB','GB','TB','PB','EB','ZB','YB']
- : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
- var u = -1;
- do {
- bytes /= thresh;
- ++u;
- } while(Math.abs(bytes) >= thresh && u < units.length - 1);
- return bytes.toFixed(1)+' '+units[u];
-}
-
-function trim(string) {
- var newStr = string.substring(0, 10);
- if(newStr.length !== string.length)
- newStr += "…";
-
- return newStr;
-}
-
-function trimNum(string, num) {
- var newStr = string.substring(0, num);
- if(newStr.length !== string.length)
- newStr += "…";
-
- return newStr;
-}
-
function handleUpload(id) {
console.warn("блять...");
@@ -49,23 +17,34 @@ function handleUpload(id) {
function initGraffiti(id) {
let canvas = null;
- let msgbox = MessageBox(tr("draw_graffiti"), "
", [tr("save"), tr("cancel")], [function() {
- canvas.getImage({includeWatermark: false}).toBlob(blob => {
- let fName = "Graffiti-" + Math.ceil(performance.now()).toString() + ".jpeg";
- let image = new File([blob], fName, {type: "image/jpeg", lastModified: new Date().getTime()});
+ const msgbox = new CMessageBox({
+ title: tr("draw_graffiti"),
+ body: "
",
+ close_on_buttons: false,
+ buttons: [tr("save"), tr("cancel")],
+ callbacks: [function() {
+ canvas.getImage({includeWatermark: false}).toBlob(blob => {
+ let fName = "Graffiti-" + Math.ceil(performance.now()).toString() + ".jpeg";
+ let image = new File([blob], fName, {type: "image/jpeg", lastModified: new Date().getTime()});
+
+ fastUploadImage(id, image)
+ }, "image/jpeg", 0.92);
- fastUploadImage(id, image)
- }, "image/jpeg", 0.92);
-
- canvas.teardown();
- }, function() {
- canvas.teardown();
- }]);
+ canvas.teardown();
+ msgbox.close()
+ }, async function() {
+ const res = await msgbox.__showCloseConfirmationDialog()
+ if(res === true) {
+ canvas.teardown()
+ msgbox.close()
+ }
+ }]
+ })
let watermarkImage = new Image();
watermarkImage.src = "/assets/packages/static/openvk/img/logo_watermark.gif";
- msgbox.attr("style", "width: 750px;");
+ msgbox.getNode().attr("style", "width: 750px;");
canvas = LC.init(document.querySelector("#ovkDraw"), {
backgroundColor: "#fff",
imageURLPrefix: "/assets/packages/static/openvk/js/node_modules/literallycanvas/lib/img",
@@ -1382,6 +1361,124 @@ $(document).on("click", "#photosAttachments", async (e) => {
})
})
+async function repost(id, repost_type = 'post') {
+ const repostsCount = u(`#repostsCount${id}`)
+ const previousVal = repostsCount.length > 0 ? Number(repostsCount.html()) : 0;
+
+ MessageBox(tr('share'), `
+
+ `, [tr('send'), tr('cancel')], [
+ async () => {
+ const message = u('#repostMsgInput').nodes[0].value
+ const type = u(`input[name='repost_type']:checked`).nodes[0].value
+ const club_id = parseInt(u(`select[name='selected_repost_club']`).nodes[0].selectedOptions[0].value)
+ const as_group = u(`input[name='asGroup']`).nodes[0].checked
+ const signed = u(`input[name='signed']`).nodes[0].checked
+ const attachments = u(`#repost_attachments`).nodes[0].value
+
+ const params = {}
+ switch(repost_type) {
+ case 'post':
+ params.object = `wall${id}`
+ break
+ case 'video':
+ params.object = `video${id}`
+ break
+ }
+
+ params.message = message
+ if(type == 'group' && club_id != 0) {
+ params.group_id = club_id
+ }
+
+ if(as_group) {
+ params.as_group = Number(as_group)
+ }
+
+ if(signed) {
+ params.signed = Number(signed)
+ }
+
+ if(attachments != '') {
+ params.attachments = attachments
+ }
+
+ try {
+ res = await window.OVKAPI.call('wall.repost', params)
+ if(repostsCount.length > 0) {
+ repostsCount.html(previousVal + 1)
+ } else {
+ u('#reposts' + id).append(`(
1)`)
+ }
+
+ NewNotification(tr('information_-1'), tr('shared_succ'), null, () => {window.location.assign(`/wall${res.pretty_id}`)});
+ } catch(e) {
+ console.error(e)
+ fastError(e.message)
+ }
+
+ xhr = new XMLHttpRequest();
+ xhr.onload = (function() {
+ if(xhr.responseText.indexOf("wall_owner") === -1) {
+ let jsonR = JSON.parse(xhr.responseText);
+
+ repostsCount != null ?
+ repostsCount.innerHTML = prevVal+1 :
+ document.getElementById("reposts"+id).insertAdjacentHTML("beforeend", "(
1)") //для старого вида постов
+ }
+ });
+ },
+ Function.noop
+ ]);
+
+ u('.ovk-diag-body').attr('style', 'padding: 14px;')
+ u('.ovk-diag-body').on('change', `input[name='repost_type']`, (e) => {
+ const value = e.target.value
+
+ switch(value) {
+ case 'wall':
+ u('#repost_signs').attr('style', 'display:none')
+ u(`select[name='selected_repost_club']`).attr('style', 'display:none')
+ break
+ case 'group':
+ u('#repost_signs').attr('style', 'display:flex')
+ u(`select[name='selected_repost_club']`).attr('style', 'display:block')
+ break
+ }
+ })
+
+ const clubs = await window.OVKAPI.call('groups.get', {'filter': 'admin', 'count': 100})
+ clubs.items.forEach(club => {
+ u(`select[name='selected_repost_club']`).append(`
`)
+ })
+}
+
$(document).on("click", "#add_image", (e) => {
let isGroup = e.currentTarget.closest(".avatar_block").dataset.club != null
let group = isGroup ? e.currentTarget.closest(".avatar_block").dataset.club : 0
diff --git a/Web/static/js/messagebox.js b/Web/static/js/messagebox.js
index c9fa9c31..33b3b3cf 100644
--- a/Web/static/js/messagebox.js
+++ b/Web/static/js/messagebox.js
@@ -1,42 +1,148 @@
Function.noop = () => {};
-function MessageBox(title, body, buttons, callbacks) {
- if(u(".ovk-diag-cont").length > 0) return false;
-
- document.querySelector("html").style.overflowY = "hidden"
- let dialog = u(
- `
`);
- u("body").addClass("dimmed").append(dialog);
-
- buttons.forEach((text, callback) => {
- u(".ovk-diag-action").append(u(`
`));
- let button = u(u(".ovk-diag-action > button.button").last());
-
- button.on("click", function(e) {
- let __closeDialog = () => {
-
- if(document.querySelector(".ovk-photo-view-dimmer") == null && document.querySelector(".ovk-fullscreen-player") == null) {
- u("body").removeClass("dimmed");
- document.querySelector("html").style.overflowY = "scroll"
+class CMessageBox {
+ constructor(options = {}) {
+ const title = options.title ?? 'Untitled'
+ const body = options.body ?? '
'
+ const buttons = options.buttons ?? []
+ const callbacks = options.callbacks ?? []
+ const close_on_buttons = options.close_on_buttons ?? true
+ const unique_name = options.unique_name ?? null
+
+ this.title = title
+ this.body = body
+ this.id = random_int(0, 10000)
+ this.close_on_buttons = close_on_buttons
+ this.unique_name = unique_name
+
+ u('body').addClass('dimmed').append(this.__getTemplate())
+ u('html').attr('style', 'overflow-y:hidden')
+
+ buttons.forEach((text, callback) => {
+ this.getNode().find('.ovk-diag-action').append(u(`
`))
+ let button = u(this.getNode().find('.ovk-diag-action > button.button').last())
+ button.on("click", (e) => {
+ callbacks[callback]()
+
+ if(close_on_buttons) {
+ this.close()
}
-
- u(".ovk-diag-cont").remove();
- };
-
- Reflect.apply(callbacks[callback], {
- closeDialog: () => __closeDialog(),
- $dialog: () => u(".ovk-diag-cont")
- }, [e]);
+ })
+ })
+
+ window.messagebox_stack.push(this)
+ }
+
+ __getTemplate() {
+ return u(
+ `
+
+
${this.title}
+
${this.body}
+
+
+
`)
+ }
+
+ getNode() {
+ return u(`.ovk-diag-cont[data-id='${this.id}']`)
+ }
+
+ async __showCloseConfirmationDialog() {
+ if(window.messagebox_stack.find(item => item.unique_name == 'close_confirmation') != null) {
+ return
+ }
+
+ return new Promise((resolve, reject) => {
+ const msg = new CMessageBox({
+ title: tr('exit_noun'),
+ body: tr('exit_confirmation'),
+ warn_on_exit: false,
+ unique_name: 'close_confirmation',
+ buttons: [tr('no'), tr('yes')],
+ callbacks: [() => {
+ msg.close()
+ resolve(false)
+ }, () => {
+ this.__exitDialog()
+ resolve(true)
+ }]
+ })
+ })
+ }
+
+ __exitDialog() {
+ u(`.ovk-diag-cont[data-id='${this.id}']`).remove()
+ if(u('.ovk-diag-cont').length < 1) {
+ u('body').removeClass('dimmed')
+ u('html').attr('style', 'overflow-y:scroll')
+ }
+
+ const current_item = window.messagebox_stack.find(item => item.id == this.id)
+ const index_of_item = window.messagebox_stack.indexOf(current_item)
+ window.messagebox_stack = array_splice(window.messagebox_stack, index_of_item)
- __closeDialog();
- });
- });
-
- return u(".ovk-diag-cont");
+ delete this
+ }
+
+ close() {
+ this.__exitDialog()
+ }
}
+
+window.messagebox_stack = []
+
+function MessageBox(title, body, buttons, callbacks, return_msg = false) {
+ const msg = new CMessageBox({
+ title: title,
+ body: body,
+ buttons: buttons,
+ callbacks: callbacks,
+ })
+
+ if(return_msg) {
+ return msg
+ }
+
+ return msg.getNode()
+}
+
+// Close on 'Escape' key
+u(document).on('keyup', async (e) => {
+ if(e.keyCode == 27 && window.messagebox_stack.length > 0) {
+ const msg = window.messagebox_stack[window.messagebox_stack.length - 1]
+ if(!msg) {
+ return
+ }
+
+ if(msg.close_on_buttons) {
+ msg.close()
+ return
+ }
+
+ const res = await msg.__showCloseConfirmationDialog()
+ if(res === true) {
+ msg.close()
+ }
+ }
+})
+
+// Close when clicking on shadow
+u(document).on('click', 'body.dimmed .dimmer', async (e) => {
+ if(u(e.target).hasClass('dimmer')) {
+ const msg = window.messagebox_stack[window.messagebox_stack.length - 1]
+ if(!msg) {
+ return
+ }
+
+ if(msg.close_on_buttons) {
+ msg.close()
+ return
+ }
+
+ const res = await msg.__showCloseConfirmationDialog()
+ if(res === true) {
+ msg.close()
+ }
+ }
+})
\ No newline at end of file
diff --git a/Web/static/js/openvk.cls.js b/Web/static/js/openvk.cls.js
index a1b1e584..f849cdd7 100644
--- a/Web/static/js/openvk.cls.js
+++ b/Web/static/js/openvk.cls.js
@@ -16,19 +16,6 @@ function expand_comment_textarea(id) {
wi.focus();
}
-function edit_post(id, wid) {
- var el = document.getElementById('text'+wid+'_'+id);
- var ed = document.getElementById('text_edit'+wid+'_'+id);
- if (el.style.display == "none") {
- el.style.display = "block";
- ed.style.display = "none";
- } else {
- el.style.display = "none";
- ed.style.display = "block";
- }
-}
-
-
function hidePanel(panel, count = 0)
{
$(panel).toggleClass("content_title_expanded content_title_unexpanded");
@@ -189,74 +176,6 @@ document.addEventListener("DOMContentLoaded", function() { //BEGIN
})
}); //END ONREADY DECLS
-async function repostPost(id, hash) {
- uRepostMsgTxt = `
-
${tr('auditory')}:
-
${tr("in_wall")}
-
${tr("in_group")}
-
-
${tr('your_comment')}:
-
-
-
-
-
-
`;
- let clubs = [];
- repostsCount = document.getElementById("repostsCount"+id)
- prevVal = repostsCount != null ? Number(repostsCount.innerHTML) : 0;
-
- MessageBox(tr('share'), uRepostMsgTxt, [tr('send'), tr('cancel')], [
- (function() {
- text = document.querySelector("#uRepostMsgInput_"+id).value;
- type = "user";
- radios = document.querySelectorAll('input[name="type"]')
- for(const r of radios)
- {
- if(r.checked)
- {
- type = r.value;
- break;
- }
- }
- groupId = document.querySelector("#groupId").value;
- asGroup = asgroup.checked == true ? 1 : 0;
- signed = signed.checked == true ? 1 : 0;
- hash = encodeURIComponent(hash);
-
- xhr = new XMLHttpRequest();
- xhr.open("POST", "/wall"+id+"/repost?hash="+hash, true);
- xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
- xhr.onload = (function() {
- if(xhr.responseText.indexOf("wall_owner") === -1)
- MessageBox(tr('error'), tr('error_repost_fail'), [tr('ok')], [Function.noop]);
- else {
- let jsonR = JSON.parse(xhr.responseText);
- NewNotification(tr('information_-1'), tr('shared_succ'), null, () => {window.location.href = "/wall" + jsonR.wall_owner});
- repostsCount != null ?
- repostsCount.innerHTML = prevVal+1 :
- document.getElementById("reposts"+id).insertAdjacentHTML("beforeend", "(
1)") //для старого вида постов
- }
- });
- xhr.send('text='+encodeURI(text) + '&type='+type + '&groupId='+groupId + "&asGroup="+asGroup + "&signed="+signed);
- }),
- Function.noop
- ]);
-
- try
- {
- clubs = await API.Groups.getWriteableClubs();
- for(const el of clubs) {
- document.getElementById("groupId").insertAdjacentHTML("beforeend", `
`)
- }
-
- } catch(rejection) {
- console.error(rejection)
- document.getElementById("group").setAttribute("disabled", "disabled")
- }
-}
-
function setClubAdminComment(clubId, adminId, hash) {
MessageBox("Изменить комментарий к администратору", `