Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <template>
- <div class="my-app">
- <h1>CTI OMNI</h1>
- <b-alert class="form col-md-7 col-md-offset-3" variant="danger" dismissible :show="showDismissibleAlert" @dismissed="showDismissibleAlert=false">
- {{errorMessage}}
- </b-alert>
- <div class="form col-md-4 col-md-offset-4" v-if="enterName">
- <label for="username">Введите ваше имя:</label>
- <br>
- <input id="username" type="text" class="form-control" v-model="username" v-on:keyup.enter="connectToChat">
- <br>
- <div v-if="selectedRole.label === 'Оператор'">
- <label for="password">Введите ваш пароль:</label><br>
- <input id="password" type="password" v-model="password" class="form-control" v-on:keyup.enter="connectToChat">
- </div>
- <br>
- <label for="selectedRole">Ваша роль:</label><br>
- <select id="selectedRole" v-model="selectedRole.label" class="form-control">
- <option v-for="role in roles">{{ role.label }}</option>
- </select>
- <br>
- <br>
- <div v-if="selectedRole.label === 'Клиент'">
- <button class="btn btn-primary col-md-6 col-md-offset-3" v-on:click="connectToChat">Войти в чат</button>
- </div>
- <div v-else>
- <button class="btn btn-danger col-md-6 col-md-offset-3" v-on:click="login">Войти в АРМ оператора</button>
- </div>
- <br>
- <br>
- </div>
- <div id="main-container" v-else>
- <div id="users-list">
- <h3>Пользователи онлайн:</h3>
- <ul>
- <transition-group name="user-appear">
- <li v-for="user in users" v-bind:key="user.user">
- <a @click="enterToPrivate">{{user.user}} ({{user.online_at}})</a>
- </li>
- </transition-group>
- </ul>
- </div>
- <div id="messages-list" ref="scrollbar">
- <ul>
- <transition-group name="message-appear">
- <li v-for="message in messages" v-bind:key="message">
- <div class="message-metadata">
- <span class="username">{{message.username}}</span>
- <span class="received-at">{{message.received_at}}</span>
- </div>
- {{message.body}}
- </li>
- </transition-group>
- </ul>
- </div>
- <div id="your-message">
- <input type="text" placeholder="What do you have to say?" v-model="message" v-on:keyup.enter="sendMessage">
- </div>
- </div>
- </div>
- </template>
- <script>
- import {
- Socket,
- Presence
- } from "phoenix"
- import gql from 'graphql-tag'
- export default {
- data() {
- return {
- socket: null,
- channel: null,
- messages: [],
- message: "",
- username: "e.batogov@cti.ru",
- password: "qweasd123",
- showDismissibleAlert: false,
- errorMessage: "",
- token: "",
- userId: "",
- enterName: true,
- hello: '',
- roles: [{
- id: "customer",
- label: "Клиент"
- },
- {
- id: "operator",
- label: "Оператор"
- }
- ],
- selectedRole: {
- id: "operator",
- label: "Оператор"
- },
- users: [],
- remoteUsers: ""
- }
- },
- methods: {
- login() {
- this.$apollo.mutate({
- mutation: gql `
- mutation UserLogin($username: String!, $password: String!) {
- login(email: $username, password: $password) {
- userId
- token
- }
- }`,
- variables: {
- username: this.username,
- password: this.password
- }
- }).then((data) => {
- this.enterName = false;
- this.token = data.data.login.token;
- this.userId = data.data.login.userId;
- }).catch((error) => {
- this.enterName = true;
- this.showDismissibleAlert = true;
- this.errorMessage = "Ошибка входа в систему. Проверьте имя и пароль";
- })
- let presences = {}
- this.enterName = false;
- this.messages = [];
- this.socket = new Socket("/socket", {
- params: {
- username: this.username
- }
- }),
- this.socket.connect();
- this.channel = this.socket.channel(`room:${this.userId}`, {
- guardian_token: this.token
- });
- this.channel.on("new_msg", payload => {
- payload.received_at = new Date(payload.received_at * 1000).toLocaleString();
- this.messages.push(payload);
- });
- this.channel.on("presence_state", state => {
- presences = Presence.syncState(presences, state)
- this.assignUsers(presences)
- })
- this.channel.on("presence_diff", diff => {
- presences = Presence.syncDiff(presences, diff)
- this.assignUsers(presences)
- })
- this.channel.join()
- .receive("ok", response => {
- console.log("Joined successfully", response)
- })
- .receive("error", response => {
- console.log("Unable to join", response)
- })
- },
- sendMessage() {
- this.channel.push("new_msg", {
- body: this.message
- })
- this.message = ''
- },
- connectToChat() {
- let presences = {}
- this.enterName = false
- this.socket = new Socket("/socket", {
- params: {
- username: this.username
- }
- }),
- this.socket.connect()
- this.channel = this.socket.channel("room:lobby", {});
- this.channel.on("new_msg", payload => {
- payload.received_at = new Date(payload.received_at * 1000).toLocaleString();
- this.messages.push(payload);
- this.$nextTick(() => {
- var chatArea = this.$refs.scrollbar.$el;
- chatArea.scrollTop = chatArea.scrollHeight
- })
- });
- this.channel.on("presence_state", state => {
- presences = Presence.syncState(presences, state)
- this.assignUsers(presences)
- })
- this.channel.on("presence_diff", diff => {
- presences = Presence.syncDiff(presences, diff)
- this.assignUsers(presences)
- })
- this.channel.join()
- .receive("ok", response => {
- console.log("Joined successfully", response)
- })
- .receive("error", response => {
- console.log("Unable to join", response)
- })
- },
- assignUsers(presences) {
- let formatTimestamp = (timestamp) => {
- timestamp = parseInt(timestamp)
- let date = new Date(timestamp)
- return date.toLocaleTimeString()
- }
- this.users = Presence.list(presences, (user, {
- metas: metas
- }) => {
- return {
- user: user,
- online_at: formatTimestamp(metas[0].online_at)
- }
- })
- }
- }
- }
- </script>
- <style lang="sass">
- .my-app {
- h1 {
- text-align: center;
- }
- #main-container {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- display: flex;
- overflow: hidden;
- }
- #users-list {
- background-color: #008bdf;
- width: 250px;
- height: 100vh;
- overflow-y: scroll;
- h3 {
- font-size: 0.9em;
- margin-left: 10px;
- color: rgba(255, 255, 255, 0.7);
- }
- ul {
- list-style: none;
- padding-left: 20px;
- color: rgba(255, 255, 255, 0.9);
- li {
- &.user-appear-enter-active,
- &.user-appear-leave-active {
- transition: all 0.2s;
- }
- &.user-appear-enter,
- &.user-appear-leave-active {
- opacity: 0;
- transform: translateX(-15px);
- }
- }
- }
- }
- #messages-list {
- padding-top: 20px;
- padding-left: 20px;
- overflow-y: scroll;
- overflow: auto ;
- flex: 1;
- ul {
- list-style: none;
- padding: 0;
- li {
- padding: 5px 0;
- &.message-appear-enter-active,
- &.message-appear-leave-active {
- transition: all 0.2s;
- }
- &.message-appear-enter,
- &.message-appear-leave-active {
- opacity: 0;
- transform: translateY(20px);
- }
- .message-metadata {
- .username {
- font-weight: bold;
- }
- .received-at {
- color: rgba(0, 0, 0, 0.4);
- margin-left: 5px;
- font-size: 0.9em;
- }
- }
- }
- }
- }
- #your-message {
- position: fixed;
- bottom: 0;
- left: 250px;
- right: 0;
- background: rgba(255, 255, 255, 0.95);
- padding: 15px;
- input {
- width: 100%;
- padding: 5px 8px;
- border-radius: 3px;
- outline: 0;
- border: 1px solid #ddd;
- }
- }
- }
- </style>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement