Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BotUI: Show loading animation before actions

Using BotUI (Docs) I'd like to have the loading animation, which is displayed before messages appear, also displayed before actions (e.g. buttons) appear.

var botui = new BotUI('hello-world');

botui.message.add({
  content: 'Hello world from bot!'
}).then(function() {
  return botui.message.add({
    delay: 3000,
    human: true,
    content: 'Hello world from human!'
  });
}).then(function() {
  return botui.message.add({
    delay: 3000,
    content: 'Another hello world from bot!'
  });
}).then(function() {
  return botui.message.add({
    delay: 3000,
    human: true,
    content: 'Another hello world from human!'
  });
}).then(function () {
  return botui.action.button({
    delay: 3000,
    action: [{
      text: 'Some button',
      value: 'button1'
    }, {
      text: 'Another button',
      value: 'button2'
    }]
  });
}).then(function (res) {
  if(res.value == 'button1') {
    console.log('Some button was clicked.');
  }
  if(res.value == 'button2') {
    console.log('Another button was clicked.');
  }
});
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
.botui-container {
  font-size: 14px;
  background-color: #fff;
  font-family: "Open Sans", sans-serif;
}

.botui-messages-container {
  padding: 10px 20px;
}

.botui-actions-container {
  padding: 10px 20px;
}

.botui-message {
  min-height: 30px;
}

.botui-message-content {
  padding: 7px 13px 17px 13px;
  border-radius: 15px;
  color: #595a5a;
  background-color: #ebebeb;
}

.botui-message-content.human {
  color: #f7f8f8;
  background-color: #919292;
}

.botui-message-content.text {
  line-height: 1.3;
}

.botui-message-content.loading {
  background-color: rgba(206, 206, 206, 0.5);
  line-height: 1.3;
  text-align: center;
}

.botui-message-content.embed {
  padding: 5px;
  border-radius: 5px;
}

.botui-message-content-link {
  color: #919292;
}

.botui-actions-text-input {
  border: 0;
  outline: 0;
  border-radius: 0;
  padding: 5px 7px;
  font-family: "Open Sans", sans-serif;
  background-color: transparent;
  color: #595a5a;
  border-bottom: 1px solid #919292;
}

.botui-actions-text-submit {
  color: #fff;
  width: 30px;
  padding: 5px;
  height: 30px;
  line-height: 1;
  border-radius: 50%;
  border: 1px solid #919292;
  background: #777979;
}

.botui-actions-buttons-button {
  border: 0;
  color: #fff;
  line-height: 1;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  padding: 7px 15px;
  border-radius: 4px;
  font-family: "Open Sans", sans-serif;
  background: #777979;
  box-shadow: 2px 3px 4px 0 rgba(0, 0, 0, 0.25);
}

.botui-actions-text-select {
  border: 0;
  outline: 0;
  border-radius: 0;
  padding: 5px 7px;
  font-family: "Open Sans", sans-serif;
  background-color: transparent;
  color: #595a5a;
  border-bottom: 1px solid #919292;
}

.botui-actions-text-searchselect {
  border: 0;
  outline: 0;
  border-radius: 0;
  padding: 5px 7px;
  font-family: "Open Sans", sans-serif;
  background-color: transparent;
  color: #595a5a;
  border-bottom: 1px solid #919292;
}

.botui-actions-text-searchselect .dropdown-toggle {
  border: none !important;
}

.botui-actions-text-searchselect .selected-tag {
  background-color: transparent !important;
  border: 0 !important;
}

.slide-fade-enter-active {
  transition: all 0.3s ease;
}

.slide-fade-enter,
.slide-fade-leave-to {
  opacity: 0;
  transform: translateX(-10px);
}

.dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 0.5rem;
  display: inline-block;
  background-color: #919292;
}

.dot:nth-last-child(1) {
  margin-left: 0.3rem;
  animation: loading 0.6s 0.3s linear infinite;
}

.dot:nth-last-child(2) {
  margin-left: 0.3rem;
  animation: loading 0.6s 0.2s linear infinite;
}

.dot:nth-last-child(3) {
  animation: loading 0.6s 0.1s linear infinite;
}

@keyframes loading {
  0% {
    transform: translate(0, 0);
    background-color: #ababab;
  }
  25% {
    transform: translate(0, -3px);
  }
  50% {
    transform: translate(0, 0);
    background-color: #ababab;
  }
  75% {
    transform: translate(0, 3px);
  }
  100% {
    transform: translate(0, 0);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/botui/build/botui.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/botui/build/botui.min.css">
<div class="botui-app-container" id="hello-world">
  <bot-ui></bot-ui>
</div>

At least I managed to identify the relevant template part in botui.js.

<div v-if=\"msg.loading\" class=\"botui-message-content loading\"><i class=\"dot\"></i><i class=\"dot\"></i><i class=\"dot\"></i></div>

But since the contents of the botui-actions-container are loaded only after the delay I am unable to display the loading animation before the buttons appear.

like image 856
Three Year Old Avatar asked Nov 19 '25 19:11

Three Year Old


2 Answers

You are trying to change the inner working of a third party component. This is normally a bad practice. In this case probably the best way is to open a new issue on their Github repository. Ask them exactly what you need and maybe they will implement the requested feature for you.

like image 179
Ferry Kranenburg Avatar answered Nov 22 '25 08:11

Ferry Kranenburg


This can be done without changing the inner working of BotUI, by using botui.message.add (to use the loading feature) immediately followed by botui.message.remove using the index parameter of the last message. Then use the action you want. This makes the loading appears before the action as requested, despite botui.action not having a loading parameter.

Here is the code that I use, with botui.action.button, but you can use any action. If you use delay: 0 for the action, the action appears instead of the loading, without any blank message that would appear if you do not remove the initial message.

// add an empty message to use the "loading" feature not available with action
botui.message.add({
    delay: 2000,
    loading: true,
    content: ''
}).then(function (index) {
    // get the index of the empty message and delete it
    botui.message.remove(index);
    // display action with 0 delay
    botui.action.button({
        delay: 0,
        action: [{
            text: 'Action 1',
            value: 'a1'
        }, {
            text: 'Action 2',
            value: 'a2'
        }]
    }).then(function (res) {
        botui.message.bot({
            delay: 1000,
            content: 'action chosen: ' + res.value
        });
    });
});
like image 29
Jeremie Avatar answered Nov 22 '25 08:11

Jeremie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!