From 6b7994e6e9157e0c47b84a4396287fa72c307d95 Mon Sep 17 00:00:00 2001
From: David Siegfried <david.siegfried@uni-vechta.de>
Date: Fri, 5 Apr 2024 06:17:11 +0000
Subject: [PATCH] refine blubber-compose-dialog, fixes #3952

Closes #3952

Merge request studip/studip!2810
---
 app/controllers/blubber.php                   | 51 +++++-----
 app/views/blubber/compose.php                 | 92 +++++++++++--------
 .../assets/stylesheets/scss/blubber.scss      | 11 +--
 templates/blubber/private_context.php         | 12 +--
 4 files changed, 85 insertions(+), 81 deletions(-)

diff --git a/app/controllers/blubber.php b/app/controllers/blubber.php
index c0490f03d37..6588014be44 100644
--- a/app/controllers/blubber.php
+++ b/app/controllers/blubber.php
@@ -135,7 +135,7 @@ class BlubberController extends AuthenticatedController
                     'user_id' => $user_id,
                 ]);
             }
-            $this->redirect("blubber/index/{$blubber->getId()}");
+            $this->relocate("blubber/index/{$blubber->getId()}");
             return;
         }
 
@@ -271,13 +271,12 @@ class BlubberController extends AuthenticatedController
 
         $output = [];
         foreach ($_FILES as $file) {
-            $newfile = null; //is filled below
             $file_ref = null; //is also filled below
 
             if ($file['size']) {
                 $document['user_id'] = $GLOBALS['user']->id;
-                $document['filesize'] = $file['size'];
-
+                $success = false;
+                $url = '';
                 try {
                     $root_dir = Folder::findTopFolder($GLOBALS['user']->id);
                     $root_dir = $root_dir->getTypedFolder();
@@ -339,7 +338,6 @@ class BlubberController extends AuthenticatedController
                     }
                 } catch (Exception $e) {
                     $output['errors'][] = $e->getMessage();
-                    $success = false;
                 }
 
                 if ($success) {
@@ -373,21 +371,22 @@ class BlubberController extends AuthenticatedController
         }
         PageLayout::setTitle(_('Person hinzufügen'));
         if (Request::isPost() && Request::option('user_id')) {
-            $query = "INSERT IGNORE INTO blubber_mentions
-                      SET thread_id = :thread_id,
-                          user_id = :user_id,
-                          external_contact = 0,
-                          mkdate = UNIX_TIMESTAMP()";
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute([
-                'thread_id' => $thread_id,
-                'user_id' => Request::option('user_id'),
-            ]);
-            $this->response->add_header('X-Dialog-Execute', 'STUDIP.Blubber.refreshThread');
-            $this->response->add_header('X-Dialog-Close', '1');
-            $this->render_json([
-                'thread_id' => $thread_id,
-            ]);
+            $data = [
+                'user_id'          => Request::option('user_id'),
+                'thread_id'        => $thread_id,
+                'external_contact' => 0,
+            ];
+
+            $blubber_mention = BlubberMention::findOneBySQL('user_id = ? AND thread_id = ?', [Request::option('user_id'), $thread_id]);
+
+            if ($blubber_mention) {
+                $blubber_mention->setData($data);
+            } else {
+                $blubber_mention = BlubberMention::create($data);
+            }
+            $blubber_mention->store();
+            $this->relocate('blubber/index/' . $thread_id);
+            return;
         }
     }
 
@@ -408,13 +407,9 @@ class BlubberController extends AuthenticatedController
                 CourseAvatar::getAvatar($course->getId())->createFromUpload('avatar');
             }
 
-            $query = "SELECT user_id
-                      FROM blubber_mentions
-                      WHERE thread_id = ?";
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute([$this->thread->id]);
-            foreach ($statement->fetchFirst() as $user_id) {
-                CourseMember::insertCourseMember($course->getId(), $user_id, $user_id === $this->thread['user_id'] ? 'dozent' : 'tutor');
+            $blubber_mentions = BlubberMention::findBySQL('thread_id = ?', [$this->thread->id]);
+            foreach ($blubber_mentions as $blubber_mention) {
+                CourseMember::insertCourseMember($course->getId(), $blubber_mention->user_id, $blubber_mention->user_id === $this->thread['user_id'] ? 'dozent' : 'tutor');
             }
 
             $this->thread['context_type'] = 'course';
@@ -430,7 +425,7 @@ class BlubberController extends AuthenticatedController
                 true
             );
 
-            PageLayout::postSuccess(sprintf(_("Studiengruppe '%s' wurde angelegt."), htmlReady($course['name'])));
+            PageLayout::postSuccess(sprintf(_('Studiengruppe "%s" wurde angelegt.'), htmlReady($course['name'])));
             $this->redirect(URLHelper::getURL('seminar_main.php', ['auswahl' => $course->getId()]));
         }
     }
diff --git a/app/views/blubber/compose.php b/app/views/blubber/compose.php
index 3b8b2a0de8a..3ea46c4d871 100644
--- a/app/views/blubber/compose.php
+++ b/app/views/blubber/compose.php
@@ -1,68 +1,79 @@
-<form class="default" action="<?= $controller->compose($thread ? $thread->getId() : null) ?>" method="post">
+<?php
+/**
+ * @var BlubberController $controller
+ * @var BlubberThread $thread
+ * @var Contact[] $contacts
+ */
+?>
 
-    <?= CSRFProtection::tokenTag() ?>
+<form class="default" action="<?= $controller->compose($thread ? $thread->getId() : null) ?>" method="post" data-dialog>
 
-    <div <?= !$thread ? "" : 'style="display: none;"' ?>>
-        <div class="file_select_possibilities">
+    <?= CSRFProtection::tokenTag() ?>
 
-            <a href="#" onclick="jQuery('.file_select_possibilities').hide(); jQuery('.private_blubber_composer').show(); return false;">
+    <div class="file_select_possibilities" <?= !$thread ? "" : 'style="display: none;"' ?>>
+        <div>
+            <a href="#"
+               onclick="$('.file_select_possibilities').hide(); $('.private_blubber_composer').show(); return false;">
                 <?= Icon::create('group3')->asImg(50) ?>
                 <?= _('Kontakte') ?>
             </a>
 
-            <a href="<?= $controller->link_for("blubber/index/global") ?>">
+            <a href="<?= $controller->link_for('blubber/index/global') ?>">
                 <?= Icon::create('globe')->asImg(50) ?>
                 <?= _('Öffentlich') ?>
             </a>
 
             <? if (!$GLOBALS['perm']->have_perm('admin')) : ?>
-                <a href="#" onclick="jQuery('.file_select_possibilities').hide(); jQuery('.course_blubber_composer').show(); return false;">
+                <a href="#"
+                   onclick="$('.file_select_possibilities').hide(); $('.course_blubber_composer').show(); return false;">
                     <?= Icon::create('seminar')->asImg(50) ?>
                     <?= _('Veranstaltung') ?>
                 </a>
             <? endif ?>
-
         </div>
     </div>
 
     <div class="course_blubber_composer" style="display: none;">
-    <? if (!$GLOBALS['perm']->have_perm("admin")) : ?>
-        <ul class="clean">
-        <? foreach (CourseMember::findBySQL("INNER JOIN seminare USING (Seminar_id) WHERE user_id = ? ORDER BY seminare.name ASC", [$GLOBALS['user']->id]) as $member) : ?>
-            <li>
-                <a href="<?= $controller->to_course($member['seminar_id']) ?>">
-                    <?= CourseAvatar::getAvatar($member['seminar_id'])->getImageTag(Avatar::SMALL) ?>
-                    <?= htmlReady($member->course['name']) ?>
-                </a>
-            </li>
-        <? endforeach ?>
-        </ul>
-    <? endif ?>
+        <? if (!$GLOBALS['perm']->have_perm('admin')) : ?>
+            <ul class="clean">
+                <? foreach (CourseMember::findBySQL("INNER JOIN seminare USING (Seminar_id) WHERE user_id = ? ORDER BY seminare.name ASC", [$GLOBALS['user']->id]) as $member) : ?>
+                    <li>
+                        <a href="<?= $controller->to_course($member['seminar_id']) ?>">
+                            <?= CourseAvatar::getAvatar($member['seminar_id'])->getImageTag(Avatar::SMALL) ?>
+                            <?= htmlReady($member->course['name']) ?>
+                        </a>
+                    </li>
+                <? endforeach ?>
+            </ul>
+        <? endif ?>
     </div>
 
     <div class="private_blubber_composer" style="display: none;">
-        <label for="blubber_contacts">
-            <?= _('Kontakte') ?>
-        </label>
-        <div class="blubber_composer_select_container">
+
+        <? if (!empty($contacts)) : ?>
+            <div class="blubber_composer_select_container">
             <span class="container">
-                <select name="user_ids[]" class="select2" id="blubber_contacts" multiple>
+                <label>
+                    <?= _('Kontakte') ?>
+                    <select name="user_ids[]" class="select2" id="blubber_contacts" multiple>
                     <? foreach ($contacts as $contact) : ?>
-                        <option value="<?= htmlReady($contact['user_id']) ?>" data-avatar="<?= htmlReady(Avatar::getAvatar($contact['user_id'])->getImageTag(Avatar::SMALL)) ?>">
+                        <option value="<?= htmlReady($contact->user_id) ?>"
+                                data-avatar="<?= htmlReady(Avatar::getAvatar($contact['user_id'])->getImageTag(Avatar::SMALL)) ?>">
                             <?= htmlReady($contact->friend->getFullName()) ?>
                         </option>
                     <? endforeach ?>
                 </select>
+                </label>
             </span>
 
-            <a href="" onClick="$('#blubber_contacts').focus().select2('open'); return false;">
-                <?= Icon::create("search", "clickable")->asImg(20, ['class' => "text-bottom"]) ?>
-            </a>
-            <a href="" onClick="$('#blubber_contacts').val(null).trigger('change'); return false;">
-                <?= Icon::create("decline", "clickable")->asImg(20, ['class' => "text-bottom"]) ?>
-            </a>
-        </div>
-
+                <a href="" onClick="$('#blubber_contacts').trigger('focus').select2('open'); return false;">
+                    <?= Icon::create('search')->asImg(['class' => 'text-bottom']) ?>
+                </a>
+                <a href="" onClick="$('#blubber_contacts').val(null).trigger('change'); return false;">
+                    <?= Icon::create('decline',)->asImg(['class' => "text-bottom"]) ?>
+                </a>
+            </div>
+        <? endif ?>
         <script>
             jQuery(function ($) {
                 let format = function (state) {
@@ -83,7 +94,6 @@
                 STUDIP.Blubber.Composer.init();
             });
         </script>
-
         <div class=".more_persons">
             <?= _('Weitere Personen') ?>
 
@@ -92,19 +102,21 @@
                     <input type="hidden" name="user_ids[]" :value="user.user_id">
                     <span>{{ user.name }}</span>
                     <a href="#" @click.prevent="removeUser">
-                        <studip-icon shape="trash" :size="20" role="clickable"></studip-icon>
+                        <studip-icon shape="trash"></studip-icon>
                     </a>
                 </li>
             </ul>
+            <quicksearch :searchtype="quicksearch" name="qs" @input="addRange" :placeholder="$gettext('Suchen')"></quicksearch>
             <div class="blubber_composer_select_container">
                 <?= QuickSearch::get('search_user_id', new StandardSearch('user_id'))
-                        ->fireJSFunctionOnSelect('STUDIP.Blubber.Composer.vue.addUser')->render() ?>
+                    ->setInputStyle('width: 90%')
+                    ->fireJSFunctionOnSelect('STUDIP.Blubber.Composer.vue.addUser')->render() ?>
 
-                <a href="" onClick="$('input[name=search_user_id_parameter]').focus(); return false;">
-                    <?= Icon::create("search", "clickable")->asImg(20, ['class' => "text-bottom"]) ?>
+                <a href="" onClick="$('input[name=search_user_id_parameter]').trigger('focus'); return false;">
+                    <?= Icon::create('search')->asImg(['class' => "text-bottom"]) ?>
                 </a>
                 <a href="" onClick="STUDIP.Blubber.Composer.vue.clearUsers(); return false;">
-                    <?= Icon::create("decline", "clickable")->asImg(20, ['class' => "text-bottom"]) ?>
+                    <?= Icon::create('decline')->asImg(['class' => "text-bottom"]) ?>
                 </a>
             </div>
         </div>
diff --git a/resources/assets/stylesheets/scss/blubber.scss b/resources/assets/stylesheets/scss/blubber.scss
index 1893fd52130..ccfec80da5b 100644
--- a/resources/assets/stylesheets/scss/blubber.scss
+++ b/resources/assets/stylesheets/scss/blubber.scss
@@ -447,15 +447,12 @@
 }
 
 
-form.default {
-    .blubber_composer_select_container {
-        input, select, .container {
-            width: calc(100% - 50px);
-            display: inline-block;
-        }
+.blubber_composer_select_container {
+    input, select, .container {
+        width: 90%;
+        display: inline-block;
     }
 }
-
 .float_right {
     float: right;
 }
diff --git a/templates/blubber/private_context.php b/templates/blubber/private_context.php
index 5984f136f50..b9a5ba9532d 100644
--- a/templates/blubber/private_context.php
+++ b/templates/blubber/private_context.php
@@ -1,7 +1,7 @@
 <div class="blubber_private_info indented">
 
     <div class="icon">
-        <?= Icon::create("group3", "info")->asImg(50, ['title' => _("Dies ist ein privater Blubber.")]) ?>
+        <?= Icon::create('group3', Icon::ROLE_INFO)->asImg(50, ['title' => _('Dies ist ein privater Blubber.')]) ?>
     </div>
 
     <ul class="clean members">
@@ -13,7 +13,7 @@
                 <? $user = User::find($mention['user_id']) ?>
                 <? if ($user) : ?>
                     <? if ($user->getId() !== $GLOBALS['user']->id && count($mentions) > 2) : ?>
-                        <a class="float_right" href="<?= URLHelper::getLink("dispatch.php/blubber/write_to/".$user->getId()) ?>" data-dialog title="<?= _("Anblubbern") ?>">
+                        <a class="float_right" href="<?= URLHelper::getLink("dispatch.php/blubber/write_to/". $user->getId()) ?>" data-dialog title="<?= _("Anblubbern") ?>">
                             <?= Icon::create("blubber", "clickable")->asImg(20, ['class' => "text-bottom"]) ?>
                         </a>
                     <? endif ?>
@@ -23,7 +23,7 @@
                            data-dialog="size=auto"
                            title="<?= _("Gruppe verlassen") ?>"
                            data-confirm="<?= _("Private Konversation wirklich verlassen?") ?>">
-                            <?= Icon::create("door-leave", "clickable")->asImg(20, ['class' => "text-bottom"]) ?>
+                            <?= Icon::create('door-leave')->asImg(['class' => 'text-bottom']) ?>
                         </a>
                     <? endif ?>
                     <a href="<?= URLHelper::getLink("dispatch.php/profile", ['username' => $user['username']]) ?>">
@@ -38,8 +38,8 @@
         </li>
         <? endforeach ?>
         <li>
-            <a href="<?= URLHelper::getLink("dispatch.php/blubber/add_member_to_private/".$thread->getId()) ?>" data-dialog>
-                <?= Icon::create("add", "clickable")->asImg(25, ['class' => "text-bottom"]) ?>
+            <a href="<?= URLHelper::getLink("dispatch.php/blubber/add_member_to_private/".$thread->getId()) ?>" data-dialog="width=600;height=300">
+                <?= Icon::create('add')->asImg(25, ['class' => 'text-bottom']) ?>
             </a>
         </li>
     </ul>
@@ -53,4 +53,4 @@
             <?= _("Aus diesem Blubber eine Studiengruppe machen.") ?>
         </a>
     </div>
-<? endif ?>
\ No newline at end of file
+<? endif ?>
-- 
GitLab