Prepare for chat multiselect:
Chat selection by context menu Clear selection Fix highlighting bubbles Fix highlight first unread bubble
This commit is contained in:
parent
2289fbff07
commit
1909fe5c60
@ -11,8 +11,8 @@ import { PopupButton } from "../popup";
|
|||||||
import PopupPeer from "../popupPeer";
|
import PopupPeer from "../popupPeer";
|
||||||
import appSidebarRight from "../sidebarRight";
|
import appSidebarRight from "../sidebarRight";
|
||||||
|
|
||||||
export class ChatContextMenu {
|
export default class ChatContextMenu {
|
||||||
private buttons: (ButtonMenuItemOptions & {verify: (peerID: number, msgID: number, target: HTMLElement) => boolean})[];
|
private buttons: (ButtonMenuItemOptions & {verify: () => boolean, notDirect?: () => boolean})[];
|
||||||
private element: HTMLElement;
|
private element: HTMLElement;
|
||||||
|
|
||||||
private target: HTMLElement;
|
private target: HTMLElement;
|
||||||
@ -26,22 +26,19 @@ export class ChatContextMenu {
|
|||||||
this.init = null;
|
this.init = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bubble: HTMLElement = null;
|
let bubble: HTMLElement, bubbleContainer: HTMLElement;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bubble = findUpClassName(e.target, 'bubble__container');
|
bubbleContainer = findUpClassName(e.target, 'bubble__container');
|
||||||
|
bubble = bubbleContainer ? bubbleContainer.parentElement : findUpClassName(e.target, 'bubble');
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
|
|
||||||
if(!bubble) return;
|
|
||||||
|
|
||||||
if(e instanceof MouseEvent) e.preventDefault();
|
if(e instanceof MouseEvent) e.preventDefault();
|
||||||
if(this.element.classList.contains('active')) {
|
if(this.element.classList.contains('active')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(e instanceof MouseEvent) e.cancelBubble = true;
|
if(e instanceof MouseEvent) e.cancelBubble = true;
|
||||||
|
|
||||||
bubble = bubble.parentElement as HTMLDivElement; // bc container
|
|
||||||
|
|
||||||
const msgID = +bubble.dataset.mid;
|
const msgID = +bubble.dataset.mid;
|
||||||
if(!msgID) return;
|
if(!msgID) return;
|
||||||
|
|
||||||
@ -57,7 +54,9 @@ export class ChatContextMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.buttons.forEach(button => {
|
this.buttons.forEach(button => {
|
||||||
const good = button.verify(this.peerID, this.msgID, this.target);
|
const good = bubbleContainer ?
|
||||||
|
button.verify() :
|
||||||
|
button.notDirect && button.notDirect() && button.verify();
|
||||||
button.element.classList.toggle('hide', !good);
|
button.element.classList.toggle('hide', !good);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -77,58 +76,75 @@ export class ChatContextMenu {
|
|||||||
icon: 'reply',
|
icon: 'reply',
|
||||||
text: 'Reply',
|
text: 'Reply',
|
||||||
onClick: this.onReplyClick,
|
onClick: this.onReplyClick,
|
||||||
verify: (peerID: number, msgID: number) => (peerID > 0 || appChatsManager.hasRights(-peerID, 'send')) && msgID > 0
|
verify: () => (this.peerID > 0 || appChatsManager.hasRights(-this.peerID, 'send')) && this.msgID > 0
|
||||||
}, {
|
}, {
|
||||||
icon: 'edit',
|
icon: 'edit',
|
||||||
text: 'Edit',
|
text: 'Edit',
|
||||||
onClick: this.onEditClick,
|
onClick: this.onEditClick,
|
||||||
verify: (peerID: number, msgID: number) => appMessagesManager.canEditMessage(msgID, 'text')
|
verify: () => appMessagesManager.canEditMessage(this.msgID, 'text')
|
||||||
}, {
|
}, {
|
||||||
icon: 'copy',
|
icon: 'copy',
|
||||||
text: 'Copy',
|
text: 'Copy',
|
||||||
onClick: this.onCopyClick,
|
onClick: this.onCopyClick,
|
||||||
verify: (peerID: number, msgID: number) => !!appMessagesManager.getMessage(msgID).message
|
verify: () => !!appMessagesManager.getMessage(this.msgID).message
|
||||||
}, {
|
}, {
|
||||||
icon: 'pin',
|
icon: 'pin',
|
||||||
text: 'Pin',
|
text: 'Pin',
|
||||||
onClick: this.onPinClick,
|
onClick: this.onPinClick,
|
||||||
verify: (peerID: number, msgID: number) => {
|
verify: () => {
|
||||||
const message = appMessagesManager.getMessage(msgID);
|
const message = appMessagesManager.getMessage(this.msgID);
|
||||||
return msgID > 0 && message._ != 'messageService' && appImManager.pinnedMsgID != msgID && (peerID == $rootScope.myID || (peerID < 0 && appChatsManager.hasRights(-peerID, 'pin')));
|
return this.msgID > 0 && message._ != 'messageService' && appImManager.pinnedMsgID != this.msgID && (this.peerID == $rootScope.myID || (this.peerID < 0 && appChatsManager.hasRights(-this.peerID, 'pin')));
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
icon: 'unpin',
|
icon: 'unpin',
|
||||||
text: 'Unpin',
|
text: 'Unpin',
|
||||||
onClick: this.onUnpinClick,
|
onClick: this.onUnpinClick,
|
||||||
verify: (peerID: number, msgID: number) => appImManager.pinnedMsgID == msgID && (peerID == $rootScope.myID || (peerID < 0 && appChatsManager.hasRights(-peerID, 'pin')))
|
verify: () => appImManager.pinnedMsgID == this.msgID && (this.peerID == $rootScope.myID || (this.peerID < 0 && appChatsManager.hasRights(-this.peerID, 'pin')))
|
||||||
}, {
|
}, {
|
||||||
icon: 'revote',
|
icon: 'revote',
|
||||||
text: 'Revote',
|
text: 'Revote',
|
||||||
onClick: this.onRetractVote,
|
onClick: this.onRetractVote,
|
||||||
verify: (peerID: number, msgID) => {
|
verify: () => {
|
||||||
const message = appMessagesManager.getMessage(msgID);
|
const message = appMessagesManager.getMessage(this.msgID);
|
||||||
const poll = message.media?.poll as Poll;
|
const poll = message.media?.poll as Poll;
|
||||||
return poll && poll.chosenIndexes.length && !poll.pFlags.closed && !poll.pFlags.quiz;
|
return poll && poll.chosenIndexes.length && !poll.pFlags.closed && !poll.pFlags.quiz;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
icon: 'lock',
|
icon: 'stop',
|
||||||
text: 'Stop poll',
|
text: 'Stop poll',
|
||||||
onClick: this.onStopPoll,
|
onClick: this.onStopPoll,
|
||||||
verify: (peerID: number, msgID) => {
|
verify: () => {
|
||||||
const message = appMessagesManager.getMessage(msgID);
|
const message = appMessagesManager.getMessage(this.msgID);
|
||||||
const poll = message.media?.poll;
|
const poll = message.media?.poll;
|
||||||
return appMessagesManager.canEditMessage(msgID, 'poll') && poll && !poll.pFlags.closed && msgID > 0;
|
return appMessagesManager.canEditMessage(this.msgID, 'poll') && poll && !poll.pFlags.closed && this.msgID > 0;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
icon: 'forward',
|
icon: 'forward',
|
||||||
text: 'Forward',
|
text: 'Forward',
|
||||||
onClick: this.onForwardClick,
|
onClick: this.onForwardClick,
|
||||||
verify: (peerID: number, msgID: number) => msgID > 0
|
verify: () => this.msgID > 0
|
||||||
|
}, {
|
||||||
|
icon: 'revote',
|
||||||
|
text: 'Select',
|
||||||
|
onClick: this.onSelectClick,
|
||||||
|
verify: () => {
|
||||||
|
const message = appMessagesManager.getMessage(this.msgID);
|
||||||
|
return !message.action && !appImManager.chatSelection.selectedMids.has(this.msgID);
|
||||||
|
},
|
||||||
|
notDirect: () => true
|
||||||
|
}, {
|
||||||
|
icon: 'revote',
|
||||||
|
text: 'Clear selection',
|
||||||
|
onClick: this.onClearSelectionClick,
|
||||||
|
verify: () => {
|
||||||
|
return appImManager.chatSelection.selectedMids.has(this.msgID);
|
||||||
|
},
|
||||||
|
notDirect: () => appImManager.chatSelection.selectedMids.has(this.msgID)
|
||||||
}, {
|
}, {
|
||||||
icon: 'delete danger',
|
icon: 'delete danger',
|
||||||
text: 'Delete',
|
text: 'Delete',
|
||||||
onClick: this.onDeleteClick,
|
onClick: this.onDeleteClick,
|
||||||
verify: (peerID: number, msgID: number) => peerID > 0 || appMessagesManager.getMessage(msgID).fromID == $rootScope.myID || appChatsManager.hasRights(-peerID, 'deleteRevoke')
|
verify: () => this.peerID > 0 || appMessagesManager.getMessage(this.msgID).fromID == $rootScope.myID || appChatsManager.hasRights(-this.peerID, 'deleteRevoke')
|
||||||
}];
|
}];
|
||||||
|
|
||||||
this.element = ButtonMenu(this.buttons);
|
this.element = ButtonMenu(this.buttons);
|
||||||
@ -193,6 +209,14 @@ export class ChatContextMenu {
|
|||||||
appSidebarRight.forwardTab.open([this.msgID]);
|
appSidebarRight.forwardTab.open([this.msgID]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onSelectClick = () => {
|
||||||
|
appImManager.chatSelection.toggleByBubble(findUpClassName(this.target, 'bubble'));
|
||||||
|
};
|
||||||
|
|
||||||
|
private onClearSelectionClick = () => {
|
||||||
|
appImManager.chatSelection.cancelSelection();
|
||||||
|
};
|
||||||
|
|
||||||
private onDeleteClick = () => {
|
private onDeleteClick = () => {
|
||||||
const peerID = $rootScope.selectedPeerID;
|
const peerID = $rootScope.selectedPeerID;
|
||||||
const firstName = appPeersManager.getPeerTitle(peerID, false, true);
|
const firstName = appPeersManager.getPeerTitle(peerID, false, true);
|
||||||
|
106
src/components/chat/selection.ts
Normal file
106
src/components/chat/selection.ts
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import type { AppImManager } from "../../lib/appManagers/appImManager";
|
||||||
|
import type { AppMessagesManager } from "../../lib/appManagers/appMessagesManager";
|
||||||
|
import CheckboxField from "../checkbox";
|
||||||
|
|
||||||
|
export default class ChatSelection {
|
||||||
|
public selectedMids: Set<number> = new Set();
|
||||||
|
public isSelecting = false;
|
||||||
|
|
||||||
|
constructor(private appImManager: AppImManager, private appMessagesManager: AppMessagesManager) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleBubbleCheckbox(bubble: HTMLElement, show: boolean) {
|
||||||
|
const hasCheckbox = !!this.getCheckboxInputFromBubble(bubble);
|
||||||
|
if(show) {
|
||||||
|
if(hasCheckbox) return;
|
||||||
|
|
||||||
|
const checkboxField = CheckboxField('', bubble.dataset.mid, true);
|
||||||
|
checkboxField.label.classList.add('bubble-select-checkbox');
|
||||||
|
|
||||||
|
// * if it is a render of new message
|
||||||
|
const mid = +bubble.dataset.mid;
|
||||||
|
if(this.selectedMids.has(mid)) {
|
||||||
|
checkboxField.input.checked = true;
|
||||||
|
bubble.classList.add('is-selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
bubble.append(checkboxField.label);
|
||||||
|
} else if(hasCheckbox) {
|
||||||
|
bubble.lastElementChild.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCheckboxInputFromBubble(bubble: HTMLElement) {
|
||||||
|
return bubble.lastElementChild.tagName == 'LABEL' && bubble.lastElementChild.firstElementChild as HTMLInputElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleSelection() {
|
||||||
|
const wasSelecting = this.isSelecting;
|
||||||
|
this.isSelecting = this.selectedMids.size > 0;
|
||||||
|
|
||||||
|
if(wasSelecting == this.isSelecting) return;
|
||||||
|
|
||||||
|
this.appImManager.bubblesContainer.classList.toggle('is-selecting', !!this.selectedMids.size);
|
||||||
|
|
||||||
|
for(const mid in this.appImManager.bubbles) {
|
||||||
|
const bubble = this.appImManager.bubbles[mid];
|
||||||
|
this.toggleBubbleCheckbox(bubble, this.isSelecting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public cancelSelection() {
|
||||||
|
for(const mid of this.selectedMids) {
|
||||||
|
const bubble = this.appImManager.bubbles[mid];
|
||||||
|
if(bubble) {
|
||||||
|
this.toggleByBubble(bubble);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedMids.clear();
|
||||||
|
this.toggleSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public cleanup() {
|
||||||
|
this.isSelecting = false;
|
||||||
|
this.selectedMids.clear();
|
||||||
|
this.appImManager.bubblesContainer.classList.remove('is-selecting');
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleByBubble(bubble: HTMLElement) {
|
||||||
|
const mid = +bubble.dataset.mid;
|
||||||
|
const mids = this.appMessagesManager.getMidsByMid(mid);
|
||||||
|
|
||||||
|
const found = mids.find(mid => this.selectedMids.has(mid));
|
||||||
|
if(found) {
|
||||||
|
mids.forEach(mid => this.selectedMids.delete(mid));
|
||||||
|
} else {
|
||||||
|
mids.forEach(mid => this.selectedMids.add(mid));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toggleBubbleCheckbox(bubble, true);
|
||||||
|
const input = this.getCheckboxInputFromBubble(bubble);
|
||||||
|
input.checked = !found;
|
||||||
|
|
||||||
|
this.toggleSelection();
|
||||||
|
if(found) {
|
||||||
|
bubble.classList.add('backwards');
|
||||||
|
bubble.dataset.timeout = '' + setTimeout(() => {
|
||||||
|
delete bubble.dataset.timeout;
|
||||||
|
bubble.classList.remove('backwards', 'is-selected');
|
||||||
|
}, 200);
|
||||||
|
} else {
|
||||||
|
bubble.classList.remove('backwards');
|
||||||
|
const timeout = bubble.dataset.timeout;
|
||||||
|
if(timeout !== undefined) {
|
||||||
|
clearTimeout(+timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
bubble.classList.add('is-selected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public selectMessage(mid: number) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,16 @@
|
|||||||
const CheckboxField = (text: string, name: string) => {
|
const CheckboxField = (text: string, name: string, round = false) => {
|
||||||
const label = document.createElement('label');
|
const label = document.createElement('label');
|
||||||
label.classList.add('checkbox-field');
|
label.classList.add(round ? 'checkbox-field-round' : 'checkbox-field');
|
||||||
|
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'checkbox';
|
input.type = 'checkbox';
|
||||||
input.id = 'input-' + name;
|
input.id = 'input-' + name;
|
||||||
|
|
||||||
const span = document.createElement('span');
|
const span = document.createElement('span');
|
||||||
span.innerText = text;
|
span.classList.add('checkbox-caption');
|
||||||
|
if(text) {
|
||||||
|
span.innerText = text;
|
||||||
|
}
|
||||||
|
|
||||||
label.append(input, span);
|
label.append(input, span);
|
||||||
|
|
||||||
|
@ -716,7 +716,7 @@ export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLo
|
|||||||
const items: {size: PhotoSize.photoSize, media: any, message: any}[] = [];
|
const items: {size: PhotoSize.photoSize, media: any, message: any}[] = [];
|
||||||
|
|
||||||
// !higher msgID will be the FIRST in album
|
// !higher msgID will be the FIRST in album
|
||||||
const storage = Object.keys(appMessagesManager.groupedMessagesStorage[groupID]).map(id => +id).sort((a, b) => a - b);
|
const storage = appMessagesManager.getMidsByAlbum(groupID);
|
||||||
for(const mid of storage) {
|
for(const mid of storage) {
|
||||||
const m = appMessagesManager.getMessage(mid);
|
const m = appMessagesManager.getMessage(mid);
|
||||||
const media = m.media.photo || m.media.document;
|
const media = m.media.photo || m.media.document;
|
||||||
|
@ -238,6 +238,8 @@ class AppDocsManager {
|
|||||||
|
|
||||||
if(!thumb.url) {
|
if(!thumb.url) {
|
||||||
if('bytes' in thumb) {
|
if('bytes' in thumb) {
|
||||||
|
// * exclude from state
|
||||||
|
defineNotNumerableProperties(thumb, ['url']);
|
||||||
thumb.url = appPhotosManager.getPreviewURLFromBytes(thumb.bytes, !!doc.sticker);
|
thumb.url = appPhotosManager.getPreviewURLFromBytes(thumb.bytes, !!doc.sticker);
|
||||||
} else {
|
} else {
|
||||||
//return this.getFileURL(doc, false, thumb);
|
//return this.getFileURL(doc, false, thumb);
|
||||||
|
@ -5,12 +5,14 @@ import AudioElement from '../../components/audio';
|
|||||||
import AvatarElement from '../../components/avatar';
|
import AvatarElement from '../../components/avatar';
|
||||||
import BubbleGroups from '../../components/bubbleGroups';
|
import BubbleGroups from '../../components/bubbleGroups';
|
||||||
import { ChatAudio } from '../../components/chat/audio';
|
import { ChatAudio } from '../../components/chat/audio';
|
||||||
import { ChatContextMenu } from '../../components/chat/contextMenu';
|
import ChatContextMenu from '../../components/chat/contextMenu';
|
||||||
import { ChatInput } from '../../components/chat/input';
|
import { ChatInput } from '../../components/chat/input';
|
||||||
import { MessageRender } from '../../components/chat/messageRender';
|
import { MessageRender } from '../../components/chat/messageRender';
|
||||||
import PinnedContainer from '../../components/chat/pinnedContainer';
|
import PinnedContainer from '../../components/chat/pinnedContainer';
|
||||||
import ReplyContainer from '../../components/chat/replyContainer';
|
import ReplyContainer from '../../components/chat/replyContainer';
|
||||||
import { ChatSearch } from '../../components/chat/search';
|
import { ChatSearch } from '../../components/chat/search';
|
||||||
|
import ChatSelection from '../../components/chat/selection';
|
||||||
|
import CheckboxField from '../../components/checkbox';
|
||||||
import { horizontalMenu } from '../../components/horizontalMenu';
|
import { horizontalMenu } from '../../components/horizontalMenu';
|
||||||
import LazyLoadQueue from '../../components/lazyLoadQueue';
|
import LazyLoadQueue from '../../components/lazyLoadQueue';
|
||||||
import { formatPhoneNumber, parseMenuButtonsTo } from '../../components/misc';
|
import { formatPhoneNumber, parseMenuButtonsTo } from '../../components/misc';
|
||||||
@ -74,6 +76,7 @@ export class AppImManager {
|
|||||||
|
|
||||||
public chatInputC: ChatInput;
|
public chatInputC: ChatInput;
|
||||||
public chatAudio: ChatAudio;
|
public chatAudio: ChatAudio;
|
||||||
|
public chatSelection: ChatSelection;
|
||||||
|
|
||||||
private menuButtons: {
|
private menuButtons: {
|
||||||
search: HTMLButtonElement
|
search: HTMLButtonElement
|
||||||
@ -167,6 +170,8 @@ export class AppImManager {
|
|||||||
this.selectTab(0);
|
this.selectTab(0);
|
||||||
|
|
||||||
parseMenuButtonsTo(this.menuButtons, this.columnEl.querySelector('.chat-more-button').firstElementChild.children);
|
parseMenuButtonsTo(this.menuButtons, this.columnEl.querySelector('.chat-more-button').firstElementChild.children);
|
||||||
|
|
||||||
|
this.chatSelection = new ChatSelection(this, appMessagesManager/* this.bubblesContainer, this.bubbles */);
|
||||||
|
|
||||||
this.chatAudio = new ChatAudio();
|
this.chatAudio = new ChatAudio();
|
||||||
this.chatInfo.nextElementSibling.prepend(this.chatAudio.divAndCaption.container);
|
this.chatInfo.nextElementSibling.prepend(this.chatAudio.divAndCaption.container);
|
||||||
@ -430,6 +435,14 @@ export class AppImManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ! Trusted - due to audio autoclick
|
||||||
|
if(this.chatSelection.isSelecting && !bubble.classList.contains('service') && e.isTrusted) {
|
||||||
|
cancelEvent(e);
|
||||||
|
//console.log('bubble click', e);
|
||||||
|
this.chatSelection.toggleByBubble(bubble);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let contactDiv: HTMLElement = findUpClassName(target, 'contact');
|
let contactDiv: HTMLElement = findUpClassName(target, 'contact');
|
||||||
if(contactDiv) {
|
if(contactDiv) {
|
||||||
this.setPeer(+contactDiv.dataset.peerID);
|
this.setPeer(+contactDiv.dataset.peerID);
|
||||||
@ -1261,6 +1274,8 @@ export class AppImManager {
|
|||||||
let peerID = this.peerID;
|
let peerID = this.peerID;
|
||||||
this.peerChanged = true;
|
this.peerChanged = true;
|
||||||
|
|
||||||
|
this.chatSelection.cleanup();
|
||||||
|
|
||||||
this.avatarEl.setAttribute('peer', '' + this.peerID);
|
this.avatarEl.setAttribute('peer', '' + this.peerID);
|
||||||
this.avatarEl.update();
|
this.avatarEl.update();
|
||||||
|
|
||||||
@ -1381,13 +1396,13 @@ export class AppImManager {
|
|||||||
public highlightBubble(element: HTMLElement) {
|
public highlightBubble(element: HTMLElement) {
|
||||||
if(element.dataset.timeout) {
|
if(element.dataset.timeout) {
|
||||||
clearTimeout(+element.dataset.timeout);
|
clearTimeout(+element.dataset.timeout);
|
||||||
element.classList.remove('is-selected');
|
element.classList.remove('is-highlighted');
|
||||||
void element.offsetWidth; // reflow
|
void element.offsetWidth; // reflow
|
||||||
}
|
}
|
||||||
|
|
||||||
element.classList.add('is-selected');
|
element.classList.add('is-highlighted');
|
||||||
element.dataset.timeout = '' + setTimeout(() => {
|
element.dataset.timeout = '' + setTimeout(() => {
|
||||||
element.classList.remove('is-selected');
|
element.classList.remove('is-highlighted');
|
||||||
delete element.dataset.timeout;
|
delete element.dataset.timeout;
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
@ -1575,7 +1590,7 @@ export class AppImManager {
|
|||||||
bubble.appendChild(bubbleContainer);
|
bubble.appendChild(bubbleContainer);
|
||||||
this.bubbles[+message.mid] = bubble;
|
this.bubbles[+message.mid] = bubble;
|
||||||
} else {
|
} else {
|
||||||
const save = ['is-selected'];
|
const save = ['is-highlighted'];
|
||||||
const wasClassNames = bubble.className.split(' ');
|
const wasClassNames = bubble.className.split(' ');
|
||||||
const classNames = ['bubble'].concat(save.filter(c => wasClassNames.includes(c)));
|
const classNames = ['bubble'].concat(save.filter(c => wasClassNames.includes(c)));
|
||||||
bubble.className = classNames.join(' ');
|
bubble.className = classNames.join(' ');
|
||||||
@ -1592,6 +1607,10 @@ export class AppImManager {
|
|||||||
|
|
||||||
bubble.dataset.mid = message.mid;
|
bubble.dataset.mid = message.mid;
|
||||||
|
|
||||||
|
if(this.chatSelection.isSelecting) {
|
||||||
|
this.chatSelection.toggleBubbleCheckbox(bubble, true);
|
||||||
|
}
|
||||||
|
|
||||||
if(message._ == 'messageService') {
|
if(message._ == 'messageService') {
|
||||||
let action = message.action;
|
let action = message.action;
|
||||||
let _ = action._;
|
let _ = action._;
|
||||||
|
@ -2195,6 +2195,16 @@ export class AppMessagesManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getMidsByAlbum(grouped_id: string) {
|
||||||
|
return Object.keys(this.groupedMessagesStorage[grouped_id]).map(id => +id).sort((a, b) => a - b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getMidsByMid(mid: number) {
|
||||||
|
const message = this.messagesStorage[mid];
|
||||||
|
if(message?.grouped_id) return this.getMidsByAlbum(message.grouped_id);
|
||||||
|
else return [mid];
|
||||||
|
}
|
||||||
|
|
||||||
public saveMessages(messages: any[], options: {
|
public saveMessages(messages: any[], options: {
|
||||||
isEdited?: boolean
|
isEdited?: boolean
|
||||||
} = {}) {
|
} = {}) {
|
||||||
|
@ -154,7 +154,7 @@ export class AppPhotosManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getPreviewURLFromThumb(thumb: PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize, isSticker = false) {
|
public getPreviewURLFromThumb(thumb: PhotoSize.photoCachedSize | PhotoSize.photoStrippedSize, isSticker = false) {
|
||||||
return thumb.url ?? (thumb.url = this.getPreviewURLFromBytes(thumb.bytes, isSticker));
|
return thumb.url ?? (defineNotNumerableProperties(thumb, ['url']), thumb.url = this.getPreviewURLFromBytes(thumb.bytes, isSticker));
|
||||||
}
|
}
|
||||||
|
|
||||||
public setAttachmentPreview(bytes: Uint8Array | number[], element: HTMLElement | SVGForeignObjectElement, isSticker = false, background = false) {
|
public setAttachmentPreview(bytes: Uint8Array | number[], element: HTMLElement | SVGForeignObjectElement, isSticker = false, background = false) {
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
|
$btn-send-margin: .5625rem;
|
||||||
|
$chat-input-size: 3rem;
|
||||||
|
$chat-input-handhelds-size: 2.875rem;
|
||||||
|
|
||||||
#bubble-contextmenu > div {
|
#bubble-contextmenu > div {
|
||||||
padding: 0 84px 0 16px;
|
padding: 0 5.25 0 1rem;
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
padding: 0 60px 0 16px;
|
padding: 0 3.75rem 0 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10,10 +14,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.21);
|
box-shadow: 0px 1px 5px -1px rgba(0, 0, 0, .21);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
min-height: 56px;
|
min-height: 3.5rem;
|
||||||
max-height: 56px;
|
max-height: 3.5rem;
|
||||||
// border-bottom: 1px solid #DADCE0;
|
// border-bottom: 1px solid #DADCE0;
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
@ -248,6 +252,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 .5rem;
|
padding: 0 .5rem;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
@include respond-to(not-handhelds) {
|
@include respond-to(not-handhelds) {
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
@ -311,9 +316,19 @@
|
|||||||
#btn-record-cancel {
|
#btn-record-cancel {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: width .1s .1s, margin-right .1s .1s, visibility 0s .1s, opacity .1s 0s;
|
transition: visibility 0s .1s, opacity .1s 0s;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
// here percents can be used since there are no other transforms
|
||||||
|
transform: translateX(calc(-100% + #{-1rem + -$btn-send-margin}));
|
||||||
|
|
||||||
|
@include respond-to(handhelds) {
|
||||||
|
transform: translateX(calc(-100% + #{-.5rem + -$btn-send-margin}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-send-container {
|
.btn-send-container {
|
||||||
@ -404,8 +419,7 @@
|
|||||||
#btn-record-cancel {
|
#btn-record-cancel {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
margin-right: 9px;
|
transition: visibility 0s .1s, opacity .1s .1s;
|
||||||
transition: width .1s, margin-right .1s, visibility 0s .1s, opacity .1s .1s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlock
|
// unlock
|
||||||
@ -413,6 +427,14 @@
|
|||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.input-message {
|
||||||
|
width: calc(100% - #{$chat-input-size * 2 + $btn-send-margin * 3 + $btn-send-margin / 2});
|
||||||
|
|
||||||
|
@include respond-to(handhelds) {
|
||||||
|
width: calc(100% - #{$chat-input-handhelds-size * 2 + $btn-send-margin * 2});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#attach-file {
|
#attach-file {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -544,29 +566,30 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: calc(100% - 3.75rem);
|
width: calc(100% - #{$chat-input-size + $btn-send-margin + $btn-send-margin / 2});
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
box-shadow: 0 1px 2px 0 rgba(16, 35, 47, .07);
|
box-shadow: 0 1px 2px 0 rgba(16, 35, 47, .07);
|
||||||
margin-right: 9px;
|
|
||||||
padding: 4.5px .5rem;
|
padding: 4.5px .5rem;
|
||||||
/* padding: 3px .5rem 6px .5rem; */
|
/* padding: 3px .5rem 6px .5rem; */
|
||||||
min-height: 54px;
|
min-height: $chat-input-size;
|
||||||
max-height: 30rem;
|
max-height: 30rem;
|
||||||
caret-color: $button-primary-background;
|
caret-color: $button-primary-background;
|
||||||
flex: 1;
|
flex: 0 0 auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
transition: width .1s;
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
@include respond-to(handhelds) {
|
||||||
min-height: 46px;
|
width: calc(100% - #{$chat-input-handhelds-size + $btn-send-margin});
|
||||||
|
min-height: $chat-input-handhelds-size;
|
||||||
padding: .5px .5rem;
|
padding: .5px .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include respond-to(esg-bottom) {
|
@include respond-to(esg-bottom) {
|
||||||
min-height: 46px;
|
min-height: $chat-input-handhelds-size;
|
||||||
padding: .5px .5rem;
|
padding: .5px .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -984,6 +1007,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.is-selecting {
|
||||||
|
cursor: default !important;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
.is-in .bubble__container {
|
||||||
|
transform: translateX(2.5rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-selecting > .scrollable::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
> .scrollable {
|
> .scrollable {
|
||||||
height: auto;
|
height: auto;
|
||||||
/* position: absolute;
|
/* position: absolute;
|
||||||
|
@ -45,21 +45,42 @@ $bubble-margin: .25rem;
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
|
||||||
&.is-selected {
|
&.is-highlighted, &.is-selected, /* #bubbles.is-selecting */ & {
|
||||||
&:after {
|
&:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -50%;
|
left: -50%;
|
||||||
top: 0;
|
/* top: 0;
|
||||||
height: 100%;
|
bottom: 0; */
|
||||||
|
top: #{$bubble-margin / 2};
|
||||||
|
bottom: -#{$bubble-margin / 2};
|
||||||
content: " ";
|
content: " ";
|
||||||
background-color: rgba(0, 132, 255, .3);
|
|
||||||
animation: bubbleSelected 2s linear;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* &.is-highlighted, &.is-selected {
|
||||||
&:not(.is-group-last):after {
|
&:not(.is-group-last):after {
|
||||||
height: calc(100% + $bubble-margin);
|
height: calc(100% + #{$bubble-margin / 2}) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& + &:not(.is-group-last) {
|
||||||
|
&:after {
|
||||||
|
top: .125rem !important;
|
||||||
|
height: calc(100% - #{$bubble-margin / 2}) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
// ! if turn this on, there will be an empty space
|
||||||
|
/* &.is-highlighted, &.is-selected {
|
||||||
|
&.is-group-last:after {
|
||||||
|
bottom: #{$bubble-margin / 2} !important;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
&.is-highlighted:after {
|
||||||
|
background-color: rgba(0, 132, 255, .3);
|
||||||
|
animation: bubbleSelected 2s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-first-unread {
|
&.is-first-unread {
|
||||||
@ -78,10 +99,30 @@ $bubble-margin: .25rem;
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
background-color: rgba(255, 255, 255, 0.95);
|
background-color: rgba(255, 255, 255, 0.95);
|
||||||
|
z-index: 2;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-highlighted, &.is-selected {
|
||||||
|
&:after {
|
||||||
|
top: #{2rem + $bubble-margin} !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-selected:after, &.is-first-unread:before {
|
&.is-selected {
|
||||||
|
&:after {
|
||||||
|
background-color: rgba(77, 142, 80, .4);
|
||||||
|
animation: fade-in-opacity .2s linear forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.backwards:after {
|
||||||
|
animation: fade-in-backwards-opacity .2s linear forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//&.is-highlighted:after, &.is-first-unread:before, &.is-selected:after {
|
||||||
|
&:after, &:before {
|
||||||
width: 200%;
|
width: 200%;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@ -114,6 +155,45 @@ $bubble-margin: .25rem;
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-select-checkbox {
|
||||||
|
z-index: 2;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
//bottom: .25rem; // * by avatar
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
[type="checkbox"] {
|
||||||
|
&:not(:checked) + .checkbox-caption:after {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&:checked + .checkbox-caption {
|
||||||
|
&:after {
|
||||||
|
background-color: #61c642;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-caption {
|
||||||
|
&:before {
|
||||||
|
top: 7px !important;
|
||||||
|
left: 3px !important;
|
||||||
|
width: 6px !important;
|
||||||
|
height: 11px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, .4);
|
||||||
|
border: 2px solid #fff !important;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__container {
|
&__container {
|
||||||
//min-width: 60px;
|
//min-width: 60px;
|
||||||
@ -128,6 +208,7 @@ $bubble-margin: .25rem;
|
|||||||
width: max-content;
|
width: max-content;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
transition: .2s transform;
|
||||||
|
|
||||||
@include respond-to(not-handhelds) {
|
@include respond-to(not-handhelds) {
|
||||||
max-width: 85%;
|
max-width: 85%;
|
||||||
@ -408,6 +489,7 @@ $bubble-margin: .25rem;
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
display: flex; // lol
|
display: flex; // lol
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
195
src/scss/partials/_checkbox.scss
Normal file
195
src/scss/partials/_checkbox.scss
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
.checkbox-field {
|
||||||
|
margin: 1.25rem 0;
|
||||||
|
display: block;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0 1.125rem;
|
||||||
|
/* font-weight: 500; */
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
@include respond-to(handhelds) {
|
||||||
|
margin-bottom: 27px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-field-round {
|
||||||
|
display: block;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
[type="checkbox"] {
|
||||||
|
&:checked + .checkbox-caption {
|
||||||
|
&:before {
|
||||||
|
top: 5px;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
background-color: #4EA4F6;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-caption:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
border-color: #dadbdc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-field {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
padding-left: 3.5rem;
|
||||||
|
text-align: left;
|
||||||
|
margin: 1.25rem 0;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.hidden-widget {
|
||||||
|
cursor: default;
|
||||||
|
|
||||||
|
.radio-field-main {
|
||||||
|
&::before, &::after {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> input {
|
||||||
|
&:checked {
|
||||||
|
& ~ .radio-field-main {
|
||||||
|
&::before {
|
||||||
|
border-color: $button-primary-background;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-field-main {
|
||||||
|
&::before, &::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: .25rem;
|
||||||
|
top: 50%;
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
border: 2px solid #8d969c;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: white;
|
||||||
|
opacity: 1;
|
||||||
|
transition: border-color .1s ease, opacity .1s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
left: .5625rem;
|
||||||
|
width: .625rem;
|
||||||
|
height: .625rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $button-primary-background;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity .1s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .label {
|
||||||
|
display: block;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subLabel {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[type="checkbox"], [type="radio"] {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: var(--z-below);
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type="checkbox"] {
|
||||||
|
& + span {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 3.5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
height: 25px;
|
||||||
|
line-height: 25px;
|
||||||
|
user-select: none;
|
||||||
|
transition: .2s opacity;
|
||||||
|
|
||||||
|
&:before, &:after {
|
||||||
|
content: '';
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
border-radius: 2px;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
z-index: 0;
|
||||||
|
border: 2px solid $button-primary-background;
|
||||||
|
border-radius: 3px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:checked) + span:before {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
left: 6px;
|
||||||
|
top: 10px;
|
||||||
|
transform: rotateZ(45deg);
|
||||||
|
transform-origin: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:checked + span:before {
|
||||||
|
top: 4px;
|
||||||
|
left: -1px;
|
||||||
|
width: 8px;
|
||||||
|
height: 14px;
|
||||||
|
border-top: 2px solid transparent;
|
||||||
|
border-left: 2px solid transparent;
|
||||||
|
border-right: 2px solid #fff;
|
||||||
|
border-bottom: 2px solid #fff;
|
||||||
|
transform: rotateZ(45deg);
|
||||||
|
transform-origin: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:checked) + span:after {
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: #8d969c;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:checked + span:after {
|
||||||
|
background-color: $button-primary-background;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled + span {
|
||||||
|
cursor: default;
|
||||||
|
opacity: .25;
|
||||||
|
}
|
||||||
|
}
|
@ -105,6 +105,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
&-ico, &-download {
|
&-ico, &-download {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -582,11 +582,6 @@
|
|||||||
padding-left: 38px;
|
padding-left: 38px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[type="checkbox"]:checked+span:before {
|
|
||||||
top: 5px;
|
|
||||||
left: 0px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,22 +665,33 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[type="checkbox"]+span {
|
[type="checkbox"] + span {
|
||||||
padding-left: 26px;
|
padding-left: 26px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox [type="checkbox"]+span:after {
|
.checkbox [type="checkbox"] {
|
||||||
border-radius: 50%;
|
& + span:after {
|
||||||
height: 20px;
|
border-radius: 50%;
|
||||||
width: 20px;
|
height: 20px;
|
||||||
border-color: #dadbdc;
|
width: 20px;
|
||||||
}
|
border-color: #dadbdc;
|
||||||
|
}
|
||||||
|
|
||||||
.checkbox [type="checkbox"]:checked+span:after {
|
&:checked {
|
||||||
background-color: #4EA4F6;
|
& + span {
|
||||||
border: none;
|
&:before {
|
||||||
|
top: 5px;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
background-color: #4EA4F6;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.folder-category-button {
|
.folder-category-button {
|
||||||
|
@ -100,6 +100,7 @@ $floating-left-sidebar: 925px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@import "partials/ico";
|
@import "partials/ico";
|
||||||
|
@import "partials/checkbox";
|
||||||
@import "partials/chatlist";
|
@import "partials/chatlist";
|
||||||
@import "partials/chat";
|
@import "partials/chat";
|
||||||
@import "partials/chatBubble";
|
@import "partials/chatBubble";
|
||||||
@ -707,176 +708,6 @@ hr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-field {
|
|
||||||
margin: 1.25rem 0;
|
|
||||||
display: block;
|
|
||||||
text-align: left;
|
|
||||||
padding: 0 1.125rem;
|
|
||||||
/* font-weight: 500; */
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
@include respond-to(handhelds) {
|
|
||||||
margin-bottom: 27px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.radio-field {
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
padding-left: 3.5rem;
|
|
||||||
text-align: left;
|
|
||||||
margin: 1.25rem 0;
|
|
||||||
line-height: 1.5rem;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.hidden-widget {
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
.radio-field-main {
|
|
||||||
&::before, &::after {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> input {
|
|
||||||
&:checked {
|
|
||||||
& ~ .radio-field-main {
|
|
||||||
&::before {
|
|
||||||
border-color: $button-primary-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.radio-field-main {
|
|
||||||
&::before, &::after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
left: .25rem;
|
|
||||||
top: 50%;
|
|
||||||
width: 1.25rem;
|
|
||||||
height: 1.25rem;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
border: 2px solid #8d969c;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: white;
|
|
||||||
opacity: 1;
|
|
||||||
transition: border-color .1s ease, opacity .1s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
left: .5625rem;
|
|
||||||
width: .625rem;
|
|
||||||
height: .625rem;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: $button-primary-background;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity .1s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* .label {
|
|
||||||
display: block;
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subLabel {
|
|
||||||
display: block;
|
|
||||||
font-size: 0.875rem;
|
|
||||||
line-height: 1rem;
|
|
||||||
color: var(--color-text-secondary);
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[type="checkbox"], [type="radio"] {
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 0;
|
|
||||||
opacity: 0;
|
|
||||||
z-index: var(--z-below);
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
[type="checkbox"] {
|
|
||||||
& + span {
|
|
||||||
position: relative;
|
|
||||||
padding-left: 3.5rem;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
height: 25px;
|
|
||||||
line-height: 25px;
|
|
||||||
user-select: none;
|
|
||||||
transition: .2s opacity;
|
|
||||||
|
|
||||||
&:before, &:after {
|
|
||||||
content: '';
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
border-radius: 2px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
height: 18px;
|
|
||||||
width: 18px;
|
|
||||||
z-index: 0;
|
|
||||||
border: 2px solid $button-primary-background;
|
|
||||||
border-radius: 3px;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(:checked) + span:before {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
left: 6px;
|
|
||||||
top: 10px;
|
|
||||||
transform: rotateZ(45deg);
|
|
||||||
transform-origin: 100% 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:checked + span:before {
|
|
||||||
top: 4px;
|
|
||||||
left: -1px;
|
|
||||||
width: 8px;
|
|
||||||
height: 14px;
|
|
||||||
border-top: 2px solid transparent;
|
|
||||||
border-left: 2px solid transparent;
|
|
||||||
border-right: 2px solid #fff;
|
|
||||||
border-bottom: 2px solid #fff;
|
|
||||||
transform: rotateZ(45deg);
|
|
||||||
transform-origin: 100% 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(:checked) + span:after {
|
|
||||||
background-color: transparent;
|
|
||||||
border-color: #8d969c;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:checked + span:after {
|
|
||||||
background-color: $button-primary-background;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled + span {
|
|
||||||
cursor: default;
|
|
||||||
opacity: .25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-wrapper > * + * {
|
.input-wrapper > * + * {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user