temp commit
This commit is contained in:
parent
4b4df5baf9
commit
78ed6430da
@ -1,11 +1,13 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/bootbox": "^5.2.0",
|
||||||
"@types/dompurify": "^2.0.0",
|
"@types/dompurify": "^2.0.0",
|
||||||
"@types/jquery": "^3.3.31",
|
"@types/jquery": "^3.3.31",
|
||||||
"@types/markdown-it": "^0.0.9",
|
"@types/markdown-it": "^0.0.9",
|
||||||
"@types/sjcl": "^1.0.28",
|
"@types/sjcl": "^1.0.28",
|
||||||
"@types/sprintf-js": "^1.1.2",
|
"@types/sprintf-js": "^1.1.2",
|
||||||
"alertifyjs": "^1.12.0",
|
"alertifyjs": "^1.12.0",
|
||||||
|
"bootbox": "^5.4.0",
|
||||||
"builder-pattern": "^1.2.3",
|
"builder-pattern": "^1.2.3",
|
||||||
"chart.js": "^2.9.3",
|
"chart.js": "^2.9.3",
|
||||||
"dompurify": "^2.0.7",
|
"dompurify": "^2.0.7",
|
||||||
@ -43,7 +45,13 @@
|
|||||||
"fuse.js": "global:Fuse",
|
"fuse.js": "global:Fuse",
|
||||||
"sjcl": "global:sjcl",
|
"sjcl": "global:sjcl",
|
||||||
"sprintf-js": "global:sprintf",
|
"sprintf-js": "global:sprintf",
|
||||||
"alertifyjs": "global:alertify"
|
"alertifyjs": "global:alertify",
|
||||||
|
"bootbox": {
|
||||||
|
"exports": "global:bootbox",
|
||||||
|
"depends": [
|
||||||
|
"@types/jquery"
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"watch": "watchify ts/src/main.ts -p [ tsify --target ES6 --noImplicitAny ] --debug -o ../resources/static/js/bundle.js"
|
"watch": "watchify ts/src/main.ts -p [ tsify --target ES6 --noImplicitAny ] --debug -o ../resources/static/js/bundle.js"
|
||||||
|
@ -66,7 +66,8 @@ const uvDeps: UserViewDeps = {
|
|||||||
userSearchCancelButton: userSearchCancelButton,
|
userSearchCancelButton: userSearchCancelButton,
|
||||||
searchService: activeUserSearchService,
|
searchService: activeUserSearchService,
|
||||||
userContactOnlineTemplate: TemplateFactory.getTemplate('user-contact-online-template'),
|
userContactOnlineTemplate: TemplateFactory.getTemplate('user-contact-online-template'),
|
||||||
userContactOfflineTemplate: TemplateFactory.getTemplate('user-contact-offline-template')
|
userContactOfflineTemplate: TemplateFactory.getTemplate('user-contact-offline-template'),
|
||||||
|
notificationService: ns
|
||||||
}
|
}
|
||||||
const userView = new UserView(uvDeps);
|
const userView = new UserView(uvDeps);
|
||||||
userModel.attach(userView);
|
userModel.attach(userView);
|
||||||
@ -79,14 +80,22 @@ Handlebars.registerHelper('avatar', function () {
|
|||||||
return '<div class="img_cont_msg"> <img src="https://static.turbosquid.com/Preview/001292/481/WV/_D.jpg" class="rounded-circle user_img_msg"> </div>';
|
return '<div class="img_cont_msg"> <img src="https://static.turbosquid.com/Preview/001292/481/WV/_D.jpg" class="rounded-circle user_img_msg"> </div>';
|
||||||
});
|
});
|
||||||
Handlebars.registerHelper('fromNow', function (date: string) {
|
Handlebars.registerHelper('fromNow', function (date: string) {
|
||||||
if(date == null)
|
if (date == null)
|
||||||
return ": Never"
|
return ": Never"
|
||||||
return moment(date).fromNow();
|
return moment(date).fromNow();
|
||||||
})
|
})
|
||||||
Handlebars.registerHelper('msgDateFormat', function (date: string) {
|
Handlebars.registerHelper('msgDateFormat', function (date: string) {
|
||||||
return moment(date).calendar(moment.now(), { lastWeek: "DD/MM/YY hh:mm A", sameElse: "DD/MM/YY hh:mm A" })
|
return moment(date).calendar(moment.now(), { lastWeek: "DD/MM/YY hh:mm A", sameElse: "DD/MM/YY hh:mm A" })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Handlebars.registerHelper('lockIcon', function (unlocked: boolean) {
|
||||||
|
switch (unlocked) {
|
||||||
|
case true: { return '<i class="fas fa-lock-open user-passphrase"></i>'; }
|
||||||
|
default: { return '<i class="fas fa-lock user-passphrase"></i>'; }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ns.success("Welcome");
|
ns.success("Welcome");
|
||||||
|
@ -94,8 +94,9 @@ export class ChatModel implements Subject<ChatMessageViewModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public clear(): void {
|
public clear(): void {
|
||||||
|
log.info("Clearing model")
|
||||||
this._messagePageMap.set(JsonAPI.contactName!, 0);
|
this._messagePageMap.set(JsonAPI.contactName!, 0);
|
||||||
this.storeUserMessages(JsonAPI.contactName!, [], "clear");
|
this.storeUserMessages(JsonAPI.contactName!, Array(), "clear");
|
||||||
this.notify({ userName: "", data: [], op: "clear" })
|
this.notify({ userName: "", data: [], op: "clear" })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { NotificationService } from "./NotificationService";
|
import { NotificationService } from "./NotificationService";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as alertify from "alertifyjs";
|
import * as alertify from "alertifyjs";
|
||||||
|
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||||
|
import log = require("loglevel");
|
||||||
|
import bootbox = require("bootbox")
|
||||||
export class AlertifyNotificationService implements NotificationService {
|
export class AlertifyNotificationService implements NotificationService {
|
||||||
|
|
||||||
private readonly _alertify = alertify;
|
private readonly _alertify = alertify;
|
||||||
constructor() {
|
constructor() {
|
||||||
this._alertify.set('notifier', 'position', 'top-center');
|
this._alertify.set('notifier', 'position', 'top-center');
|
||||||
@ -24,4 +28,84 @@ export class AlertifyNotificationService implements NotificationService {
|
|||||||
message(message: string): void {
|
message(message: string): void {
|
||||||
this._alertify.message(message);
|
this._alertify.message(message);
|
||||||
}
|
}
|
||||||
|
passphrasePrompt(vm: ActiveUserViewModel, vms: ActiveUserViewModel[], cb1: (contactName: string, passphrase: string,
|
||||||
|
lastMessageTime: string | null, op: string) => void,
|
||||||
|
cb2: () => any): void {
|
||||||
|
|
||||||
|
// alertify.myprompt || alertify.dialog('myprompt', function () {
|
||||||
|
|
||||||
|
// // document.getElementById('passphraseFormNew')!.addEventListener('submit', function (e: Event) {
|
||||||
|
// // e.preventDefault();
|
||||||
|
// // log.debug(this.querySelectorAll('input'))
|
||||||
|
// // Array.from(this.querySelectorAll('input')).map((el) => {
|
||||||
|
// // const el2 = el as HTMLInputElement;
|
||||||
|
// // vm.passphrase = el2.value;
|
||||||
|
// // vm.unlocked = true;
|
||||||
|
// // cb1(vm.userName!, vm.passphrase, null, "new");
|
||||||
|
// // cb2();
|
||||||
|
// // alertify.myprompt().close();
|
||||||
|
// // })
|
||||||
|
// // log.debug(vm)
|
||||||
|
|
||||||
|
// // })
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// main: function (content: HTMLElement) {
|
||||||
|
// log.debug(vm)
|
||||||
|
|
||||||
|
// // @ts-ignore
|
||||||
|
// this.setContent(content);
|
||||||
|
// },
|
||||||
|
|
||||||
|
// setup: function () {
|
||||||
|
// return {
|
||||||
|
// focus: {
|
||||||
|
// // @ts-ignore
|
||||||
|
// element: function () {
|
||||||
|
// // @ts-ignore
|
||||||
|
// return this.elements.body.querySelector(this.get('selector'));
|
||||||
|
// },
|
||||||
|
// select: true
|
||||||
|
// },
|
||||||
|
// options: {
|
||||||
|
// title: 'Enter Passphrase',
|
||||||
|
// basic: true,
|
||||||
|
// maximizable: false,
|
||||||
|
// resizable: false,
|
||||||
|
// padding: false
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// },
|
||||||
|
// settings: {
|
||||||
|
// // @ts-ignore
|
||||||
|
// selector: undefined
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// })
|
||||||
|
|
||||||
|
// alertify.myprompt(document.getElementById('passphraseFormNew')).set('selector', 'input[type="password"]');
|
||||||
|
|
||||||
|
if (vm.passphrase == null) {
|
||||||
|
bootbox.prompt({
|
||||||
|
title: "Please enter the passphrase",
|
||||||
|
inputType: 'password',
|
||||||
|
callback: function (result) {
|
||||||
|
if (result) {
|
||||||
|
log.debug(result);
|
||||||
|
cb1(vm.userName!, result, null, "new");
|
||||||
|
vm.unlocked = true
|
||||||
|
vms.filter(v => v.userName == vm.userName).map(v => { v.passphrase = result; v.unlocked = true })
|
||||||
|
cb2();
|
||||||
|
log.debug(vm)
|
||||||
|
log.debug(vms)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cb1(vm.userName!, vm.passphrase, null, "new");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,7 +1,10 @@
|
|||||||
|
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||||
|
|
||||||
export interface NotificationService {
|
export interface NotificationService {
|
||||||
success(message: string): void;
|
success(message: string): void;
|
||||||
error(message: string): void;
|
error(message: string): void;
|
||||||
errorWithDelay(message: string, delay: number): void;
|
errorWithDelay(message: string, delay: number): void;
|
||||||
warning(message: string): void;
|
warning(message: string): void;
|
||||||
message(message: string): void;
|
message(message: string): void;
|
||||||
|
passphrasePrompt(vm: ActiveUserViewModel, vms: ActiveUserViewModel[], cb1: (...x: any) => any, cb2: (...x: any) => any): void;
|
||||||
}
|
}
|
@ -8,10 +8,11 @@ import { UserModel } from "../model/UserModel";
|
|||||||
import { UserViewDeps } from "./UserViewDeps";
|
import { UserViewDeps } from "./UserViewDeps";
|
||||||
import { ObserverData } from "../observe/ObserverData";
|
import { ObserverData } from "../observe/ObserverData";
|
||||||
import { JsonAPI } from "../singleton/JsonAPI";
|
import { JsonAPI } from "../singleton/JsonAPI";
|
||||||
|
import { NotificationService } from "../service/NotificationService";
|
||||||
|
|
||||||
export class UserView implements Observer<ActiveUserViewModel> {
|
export class UserView implements Observer<ActiveUserViewModel> {
|
||||||
|
|
||||||
|
|
||||||
private readonly _model: UserModel;
|
private readonly _model: UserModel;
|
||||||
private readonly _chatModel: ChatModel;
|
private readonly _chatModel: ChatModel;
|
||||||
private readonly _usersListElement: HTMLElement;
|
private readonly _usersListElement: HTMLElement;
|
||||||
@ -21,6 +22,7 @@ export class UserView implements Observer<ActiveUserViewModel> {
|
|||||||
private readonly _searchService: SearchService<ActiveUserViewModel>;
|
private readonly _searchService: SearchService<ActiveUserViewModel>;
|
||||||
private readonly _userContactOnlineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
|
private readonly _userContactOnlineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
|
||||||
private readonly _userContactOfflineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
|
private readonly _userContactOfflineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
|
||||||
|
private readonly _notificationService: NotificationService;
|
||||||
|
|
||||||
constructor(deps: UserViewDeps) {
|
constructor(deps: UserViewDeps) {
|
||||||
this._model = deps.model;
|
this._model = deps.model;
|
||||||
@ -32,6 +34,7 @@ export class UserView implements Observer<ActiveUserViewModel> {
|
|||||||
this._searchService = deps.searchService;
|
this._searchService = deps.searchService;
|
||||||
this._userContactOnlineTemplate = deps.userContactOnlineTemplate;
|
this._userContactOnlineTemplate = deps.userContactOnlineTemplate;
|
||||||
this._userContactOfflineTemplate = deps.userContactOfflineTemplate;
|
this._userContactOfflineTemplate = deps.userContactOfflineTemplate;
|
||||||
|
this._notificationService = deps.notificationService;
|
||||||
|
|
||||||
this._addSearchEventListeners();
|
this._addSearchEventListeners();
|
||||||
}
|
}
|
||||||
@ -39,7 +42,8 @@ export class UserView implements Observer<ActiveUserViewModel> {
|
|||||||
update(d: ObserverData<ActiveUserViewModel>): void {
|
update(d: ObserverData<ActiveUserViewModel>): void {
|
||||||
let html: string = "";
|
let html: string = "";
|
||||||
d.data.forEach((element: ActiveUserViewModel) => {
|
d.data.forEach((element: ActiveUserViewModel) => {
|
||||||
element.online ? html += this._userContactOnlineTemplate(element) : html += this._userContactOfflineTemplate(element);
|
element.online ? html += this._userContactOnlineTemplate(element) :
|
||||||
|
html += this._userContactOfflineTemplate(element);
|
||||||
});
|
});
|
||||||
$(this._usersListElement).html(DOMPurify.sanitize(html));
|
$(this._usersListElement).html(DOMPurify.sanitize(html));
|
||||||
this._addUserCallBacks();
|
this._addUserCallBacks();
|
||||||
@ -53,10 +57,9 @@ export class UserView implements Observer<ActiveUserViewModel> {
|
|||||||
|
|
||||||
private _addUserCallBacks(): void {
|
private _addUserCallBacks(): void {
|
||||||
let userBoxes = document.getElementsByClassName('user-box');
|
let userBoxes = document.getElementsByClassName('user-box');
|
||||||
for (let i = 0; i < userBoxes.length; i++) {
|
|
||||||
let userBox = userBoxes[i];
|
Array.from(userBoxes).forEach((ub: Element) =>
|
||||||
userBoxes[i].addEventListener('click', this._userCallBack.bind(this, userBox));
|
ub.addEventListener('click', this._userCallBack.bind(this, ub)))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,10 +112,24 @@ export class UserView implements Observer<ActiveUserViewModel> {
|
|||||||
JsonAPI.contactName = userName;
|
JsonAPI.contactName = userName;
|
||||||
// @ts-ignore: Object is possibly 'null'.
|
// @ts-ignore: Object is possibly 'null'.
|
||||||
document.getElementById('user-name-span').innerText = userName;
|
document.getElementById('user-name-span').innerText = userName;
|
||||||
this._chatModel.getMessages(userName, passphrase, null, "new");
|
let vm = this._model.activeUsersList.find(vm => vm.userName === userName);
|
||||||
|
if (!vm) {
|
||||||
|
vm = new ActiveUserViewModel();
|
||||||
|
vm.userName = userName;
|
||||||
|
}
|
||||||
|
this._notificationService.passphrasePrompt(vm, this._model.activeUsersList,
|
||||||
|
this._chatModel.getMessages.bind(this._chatModel),
|
||||||
|
this._promptHandler.bind(this));
|
||||||
|
// this._chatModel.getMessages(userName, vm.passphrase, null, "new");
|
||||||
el.className += " active";
|
el.className += " active";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _promptHandler(vm: ActiveUserViewModel, vms: ActiveUserViewModel[]) {
|
||||||
|
// vms.filter(v => v.userName == vm.userName).map(v => v.userName = vm.userName)
|
||||||
|
log.debug(vms)
|
||||||
|
this._model.notify();
|
||||||
|
}
|
||||||
|
|
||||||
private _addSearchButtonEL() {
|
private _addSearchButtonEL() {
|
||||||
this._userSearchButton.addEventListener('submit', (e) => {
|
this._userSearchButton.addEventListener('submit', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -127,7 +144,7 @@ export class UserView implements Observer<ActiveUserViewModel> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let searchResult = this._searchService.search(list, searchTerm);
|
let searchResult = this._searchService.search(list, searchTerm);
|
||||||
this.update({data: searchResult, op: ""});
|
this.update({ data: searchResult, op: "" });
|
||||||
log.debug(searchResult);
|
log.debug(searchResult);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -148,7 +165,7 @@ export class UserView implements Observer<ActiveUserViewModel> {
|
|||||||
this._userSearchInputElement.value = "";
|
this._userSearchInputElement.value = "";
|
||||||
this._userSearchCancelButton.hidden = true;
|
this._userSearchCancelButton.hidden = true;
|
||||||
let list = this._model.activeUsersList;
|
let list = this._model.activeUsersList;
|
||||||
this.update({data: list, op: ""})
|
this.update({ data: list, op: "" })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { ChatModel } from "../model/ChatModel";
|
|||||||
import { SearchService } from "../service/SearchService";
|
import { SearchService } from "../service/SearchService";
|
||||||
|
|
||||||
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
import { ActiveUserViewModel } from "../viewmodel/ActiveUserViewModel";
|
||||||
|
import { NotificationService } from "../service/NotificationService";
|
||||||
|
|
||||||
export interface UserViewDeps {
|
export interface UserViewDeps {
|
||||||
model: UserModel;
|
model: UserModel;
|
||||||
@ -16,4 +17,5 @@ export interface UserViewDeps {
|
|||||||
searchService: SearchService<ActiveUserViewModel>;
|
searchService: SearchService<ActiveUserViewModel>;
|
||||||
userContactOnlineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
|
userContactOnlineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
|
||||||
userContactOfflineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
|
userContactOfflineTemplate: Handlebars.TemplateDelegate<ActiveUserViewModel>;
|
||||||
|
notificationService: NotificationService;
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
export class ActiveUserViewModel {
|
export class ActiveUserViewModel {
|
||||||
userName: string | undefined;
|
userName: string | undefined;
|
||||||
online: boolean | undefined;
|
online: boolean = false;
|
||||||
|
unlocked: boolean = false;
|
||||||
|
passphrase: string = "";
|
||||||
lastActive: Date | undefined;
|
lastActive: Date | undefined;
|
||||||
}
|
}
|
@ -2,6 +2,13 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@types/bootbox@^5.2.0":
|
||||||
|
version "5.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/bootbox/-/bootbox-5.2.0.tgz#0e51344914dbe2fbb5c720b3bc2797c467d2115a"
|
||||||
|
integrity sha512-aHKihTnKaYUqWvii5DlJDQqVud4Bp2fmfGKIaLRfsb/DzuLyvdFLnI9RKiXaNnVLQ0g6sorQZMwiV102r6UASw==
|
||||||
|
dependencies:
|
||||||
|
"@types/jquery" "*"
|
||||||
|
|
||||||
"@types/dompurify@^2.0.0":
|
"@types/dompurify@^2.0.0":
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.0.0.tgz#9616caa5bf2569aea2e4889d4f929d968c081b40"
|
resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.0.0.tgz#9616caa5bf2569aea2e4889d4f929d968c081b40"
|
||||||
@ -9,6 +16,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/trusted-types" "*"
|
"@types/trusted-types" "*"
|
||||||
|
|
||||||
|
"@types/jquery@*":
|
||||||
|
version "3.3.32"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.32.tgz#93e27fdc45dd38ee07f2f0acf34b59c1ccee036f"
|
||||||
|
integrity sha512-UKoof2mnV/X1/Ix2g+V2Ny5sgHjV8nK/UJbiYxuo4zPwzGyFlZ/mp4KaePb2VqQrqJctmcDQNA57buU84/2uIw==
|
||||||
|
dependencies:
|
||||||
|
"@types/sizzle" "*"
|
||||||
|
|
||||||
"@types/jquery@^3.3.31":
|
"@types/jquery@^3.3.31":
|
||||||
version "3.3.31"
|
version "3.3.31"
|
||||||
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.31.tgz#27c706e4bf488474e1cb54a71d8303f37c93451b"
|
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.31.tgz#27c706e4bf488474e1cb54a71d8303f37c93451b"
|
||||||
@ -258,6 +272,20 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
|
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
|
||||||
integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
|
integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==
|
||||||
|
|
||||||
|
bootbox@^5.4.0:
|
||||||
|
version "5.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/bootbox/-/bootbox-5.4.0.tgz#2857a63c270b1b797d62e4c5597e74b497267655"
|
||||||
|
integrity sha512-GCPrDwZpJsUnqzrto3ZURVafypl13+DAyE3YZx5jR5EIoTDSyREPhr77hlCuPKvM6VvXR5Mh/34W3DYMC7JE9g==
|
||||||
|
dependencies:
|
||||||
|
bootstrap "^4.4.0"
|
||||||
|
jquery "^3.4.1"
|
||||||
|
popper.js "^1.16.0"
|
||||||
|
|
||||||
|
bootstrap@^4.4.0:
|
||||||
|
version "4.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.4.1.tgz#8582960eea0c5cd2bede84d8b0baf3789c3e8b01"
|
||||||
|
integrity sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA==
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
brace-expansion@^1.1.7:
|
||||||
version "1.1.11"
|
version "1.1.11"
|
||||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
@ -1689,6 +1717,11 @@ isobject@^3.0.0, isobject@^3.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||||
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
||||||
|
|
||||||
|
jquery@^3.4.1:
|
||||||
|
version "3.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
|
||||||
|
integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==
|
||||||
|
|
||||||
js-yaml@~3.13.0:
|
js-yaml@~3.13.0:
|
||||||
version "3.13.1"
|
version "3.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
||||||
@ -2215,6 +2248,11 @@ pinkie@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
||||||
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
|
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
|
||||||
|
|
||||||
|
popper.js@^1.16.0:
|
||||||
|
version "1.16.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
||||||
|
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
|
||||||
|
|
||||||
posix-character-classes@^0.1.0:
|
posix-character-classes@^0.1.0:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||||
|
@ -256,7 +256,7 @@
|
|||||||
<span class="online_icon"></span>
|
<span class="online_icon"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="user_info">
|
<div class="user_info">
|
||||||
<span class="to-user-span">{{userName}}</span>
|
<span class="to-user-span">{{userName}}</span><span> {{{lockIcon unlocked}}}</span>
|
||||||
<p>{{userName}} is online</p>
|
<p>{{userName}} is online</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-column ml-auto">
|
<div class="d-flex flex-column ml-auto">
|
||||||
@ -273,7 +273,7 @@
|
|||||||
<img src="https://static.turbosquid.com/Preview/001292/481/WV/_D.jpg" class="rounded-circle user_img">
|
<img src="https://static.turbosquid.com/Preview/001292/481/WV/_D.jpg" class="rounded-circle user_img">
|
||||||
</div>
|
</div>
|
||||||
<div class="user_info">
|
<div class="user_info">
|
||||||
<span class="to-user-span">{{userName}}</span>
|
<span class="to-user-span">{{userName}}</span><span> {{{lockIcon unlocked}}}</span>
|
||||||
<p>Last active {{fromNow lastActive}}</p>
|
<p>Last active {{fromNow lastActive}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-column ml-auto">
|
<div class="d-flex flex-column ml-auto">
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/js/bootstrap.bundle.min.js" integrity="sha256-OUFW7hFO0/r5aEGTQOz9F/aXQOt+TwqI1Z4fbVvww04=" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/js/bootstrap.bundle.min.js" integrity="sha256-OUFW7hFO0/r5aEGTQOz9F/aXQOt+TwqI1Z4fbVvww04=" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/5.4.0/bootbox.min.js" integrity="sha256-sfG8c9ILUB8EXQ5muswfjZsKICbRIJUG/kBogvvV5sY=" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" integrity="sha256-+N4/V/SbAFiW1MPBCXnfnP9QSN3+Keu+NlB+0ev/YKQ=" crossorigin="anonymous" />
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" integrity="sha256-+N4/V/SbAFiW1MPBCXnfnP9QSN3+Keu+NlB+0ev/YKQ=" crossorigin="anonymous" />
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js" integrity="sha256-TQq84xX6vkwR0Qs1qH5ADkP+MvH0W+9E7TdHJsoIQiM=" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js" integrity="sha256-TQq84xX6vkwR0Qs1qH5ADkP+MvH0W+9E7TdHJsoIQiM=" crossorigin="anonymous"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user