Poll creator:
Non-anonymous mode support; Multiple choice mode support; Quiz mode support; Fix revote rights;
This commit is contained in:
parent
bc4c892880
commit
8d9a8b6261
@ -2,7 +2,7 @@ import appChatsManager from "../../lib/appManagers/appChatsManager";
|
|||||||
import appImManager from "../../lib/appManagers/appImManager";
|
import appImManager from "../../lib/appManagers/appImManager";
|
||||||
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
|
||||||
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
import appPeersManager from "../../lib/appManagers/appPeersManager";
|
||||||
import appPollsManager from "../../lib/appManagers/appPollsManager";
|
import appPollsManager, { Poll } from "../../lib/appManagers/appPollsManager";
|
||||||
import $rootScope from "../../lib/rootScope";
|
import $rootScope from "../../lib/rootScope";
|
||||||
import { findUpClassName } from "../../lib/utils";
|
import { findUpClassName } from "../../lib/utils";
|
||||||
import ButtonMenu, { ButtonMenuItemOptions } from "../buttonMenu";
|
import ButtonMenu, { ButtonMenuItemOptions } from "../buttonMenu";
|
||||||
@ -67,7 +67,7 @@ export class ChatContextMenu {
|
|||||||
icon: 'edit',
|
icon: 'edit',
|
||||||
text: 'Edit',
|
text: 'Edit',
|
||||||
onClick: this.onEditClick,
|
onClick: this.onEditClick,
|
||||||
verify: (peerID: number, msgID: number) => appMessagesManager.canEditMessage(msgID)
|
verify: (peerID: number, msgID: number) => appMessagesManager.canEditMessage(msgID, 'text')
|
||||||
}, {
|
}, {
|
||||||
icon: 'copy',
|
icon: 'copy',
|
||||||
text: 'Copy',
|
text: 'Copy',
|
||||||
@ -84,8 +84,8 @@ export class ChatContextMenu {
|
|||||||
onClick: this.onRetractVote,
|
onClick: this.onRetractVote,
|
||||||
verify: (peerID: number, msgID) => {
|
verify: (peerID: number, msgID) => {
|
||||||
const message = appMessagesManager.getMessage(msgID);
|
const message = appMessagesManager.getMessage(msgID);
|
||||||
const poll = message.media?.poll;
|
const poll = message.media?.poll as Poll;
|
||||||
return poll && !poll.pFlags.closed;
|
return poll && poll.chosenIndexes.length && !poll.pFlags.closed && !poll.pFlags.quiz;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
icon: 'lock',
|
icon: 'lock',
|
||||||
@ -94,7 +94,7 @@ export class ChatContextMenu {
|
|||||||
verify: (peerID: number, msgID) => {
|
verify: (peerID: number, msgID) => {
|
||||||
const message = appMessagesManager.getMessage(msgID);
|
const message = appMessagesManager.getMessage(msgID);
|
||||||
const poll = message.media?.poll;
|
const poll = message.media?.poll;
|
||||||
return appMessagesManager.canEditMessage(msgID) && message.fromID == $rootScope.myID && message.fwd_from === undefined && poll && !poll.pFlags.closed;
|
return appMessagesManager.canEditMessage(msgID, 'poll') && poll && !poll.pFlags.closed;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
icon: 'forward',
|
icon: 'forward',
|
||||||
|
17
src/components/checkbox.ts
Normal file
17
src/components/checkbox.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const CheckboxField = (text: string, name: string) => {
|
||||||
|
const label = document.createElement('label');
|
||||||
|
label.classList.add('checkbox-field');
|
||||||
|
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.type = 'checkbox';
|
||||||
|
input.id = 'input-' + name;
|
||||||
|
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.innerText = text;
|
||||||
|
|
||||||
|
label.append(input, span);
|
||||||
|
|
||||||
|
return {label, input, span};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CheckboxField;
|
@ -1,7 +1,11 @@
|
|||||||
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
import appMessagesManager from "../lib/appManagers/appMessagesManager";
|
||||||
|
import appPeersManager from "../lib/appManagers/appPeersManager";
|
||||||
import appPollsManager, { Poll } from "../lib/appManagers/appPollsManager";
|
import appPollsManager, { Poll } from "../lib/appManagers/appPollsManager";
|
||||||
import $rootScope from "../lib/rootScope";
|
import $rootScope from "../lib/rootScope";
|
||||||
|
import { findUpTag, whichChild } from "../lib/utils";
|
||||||
|
import CheckboxField from "./checkbox";
|
||||||
import { PopupElement } from "./popup";
|
import { PopupElement } from "./popup";
|
||||||
|
import RadioField from "./radioField";
|
||||||
import Scrollable from "./scrollable";
|
import Scrollable from "./scrollable";
|
||||||
import { toast } from "./toast";
|
import { toast } from "./toast";
|
||||||
|
|
||||||
@ -23,6 +27,13 @@ export default class PopupCreatePoll extends PopupElement {
|
|||||||
private scrollable: Scrollable;
|
private scrollable: Scrollable;
|
||||||
private tempID = 0;
|
private tempID = 0;
|
||||||
|
|
||||||
|
private anonymousCheckboxField: ReturnType<typeof CheckboxField>;
|
||||||
|
private multipleCheckboxField: PopupCreatePoll['anonymousCheckboxField'];
|
||||||
|
private quizCheckboxField: PopupCreatePoll['anonymousCheckboxField'];
|
||||||
|
|
||||||
|
private correctAnswers: Uint8Array[];
|
||||||
|
private quizSolutionInput: HTMLInputElement;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super('popup-create-poll popup-new-media', null, {closable: true, withConfirm: 'CREATE', body: true});
|
super('popup-create-poll popup-new-media', null, {closable: true, withConfirm: 'CREATE', body: true});
|
||||||
|
|
||||||
@ -38,11 +49,71 @@ export default class PopupCreatePoll extends PopupElement {
|
|||||||
d.classList.add('caption');
|
d.classList.add('caption');
|
||||||
d.innerText = 'Options';
|
d.innerText = 'Options';
|
||||||
|
|
||||||
this.questions = document.createElement('div');
|
this.questions = document.createElement('form');
|
||||||
this.questions.classList.add('poll-create-questions');
|
this.questions.classList.add('poll-create-questions');
|
||||||
|
|
||||||
|
const dd = document.createElement('div');
|
||||||
|
dd.classList.add('poll-create-settings');
|
||||||
|
|
||||||
|
const settingsCaption = document.createElement('div');
|
||||||
|
settingsCaption.classList.add('caption');
|
||||||
|
settingsCaption.innerText = 'Settings';
|
||||||
|
|
||||||
|
const peerID = $rootScope.selectedPeerID;
|
||||||
|
|
||||||
|
if(!appPeersManager.isBroadcast(peerID)) {
|
||||||
|
this.anonymousCheckboxField = CheckboxField('Anonymous Voting', 'anonymous');
|
||||||
|
this.anonymousCheckboxField.input.checked = true;
|
||||||
|
dd.append(this.anonymousCheckboxField.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.multipleCheckboxField = CheckboxField('Multiple Answers', 'multiple');
|
||||||
|
this.quizCheckboxField = CheckboxField('Quiz Mode', 'quiz');
|
||||||
|
|
||||||
|
this.multipleCheckboxField.input.addEventListener('change', () => {
|
||||||
|
const checked = this.multipleCheckboxField.input.checked;
|
||||||
|
this.quizCheckboxField.input.toggleAttribute('disabled', checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.quizCheckboxField.input.addEventListener('change', () => {
|
||||||
|
const checked = this.quizCheckboxField.input.checked;
|
||||||
|
|
||||||
|
(Array.from(this.questions.children) as HTMLElement[]).map(el => {
|
||||||
|
el.classList.toggle('radio-field', checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
quizElements.forEach(el => el.classList.toggle('hide', !checked));
|
||||||
|
|
||||||
|
this.multipleCheckboxField.input.toggleAttribute('disabled', checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
dd.append(this.multipleCheckboxField.label, this.quizCheckboxField.label);
|
||||||
|
|
||||||
|
const quizElements: HTMLElement[] = [];
|
||||||
|
|
||||||
|
const quizSolutionCaption = document.createElement('div');
|
||||||
|
quizSolutionCaption.classList.add('caption');
|
||||||
|
quizSolutionCaption.innerText = 'Explanation';
|
||||||
|
|
||||||
|
const quizHr = document.createElement('hr');
|
||||||
|
|
||||||
|
const quizSolutionContainer = document.createElement('div');
|
||||||
|
quizSolutionContainer.classList.add('poll-create-questions');
|
||||||
|
|
||||||
|
const quizSolutionField = InputField('Add a Comment (Optional)', 'Add a Comment (Optional)', 'solution');
|
||||||
|
this.quizSolutionInput = quizSolutionField.firstElementChild as HTMLInputElement;
|
||||||
|
|
||||||
|
const quizSolutionSubtitle = document.createElement('div');
|
||||||
|
quizSolutionSubtitle.classList.add('subtitle');
|
||||||
|
quizSolutionSubtitle.innerText = 'Users will see this comment after choosing a wrong answer, good for educational purposes.';
|
||||||
|
|
||||||
|
quizSolutionContainer.append(quizSolutionField, quizSolutionSubtitle);
|
||||||
|
|
||||||
|
quizElements.push(quizHr, quizSolutionCaption, quizSolutionContainer);
|
||||||
|
quizElements.forEach(el => el.classList.add('hide'));
|
||||||
|
|
||||||
this.body.parentElement.insertBefore(hr, this.body);
|
this.body.parentElement.insertBefore(hr, this.body);
|
||||||
this.body.append(d, this.questions);
|
this.body.append(d, this.questions, document.createElement('hr'), settingsCaption, dd, ...quizElements);
|
||||||
|
|
||||||
this.confirmBtn.addEventListener('click', this.onSubmitClick);
|
this.confirmBtn.addEventListener('click', this.onSubmitClick);
|
||||||
|
|
||||||
@ -54,17 +125,22 @@ export default class PopupCreatePoll extends PopupElement {
|
|||||||
const question = this.questionInput.value;
|
const question = this.questionInput.value;
|
||||||
|
|
||||||
if(!question.trim()) {
|
if(!question.trim()) {
|
||||||
toast('Please enter a question');
|
toast('Please enter a question.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.quizCheckboxField.input.checked && !this.correctAnswers?.length) {
|
||||||
|
toast('Please choose the correct answer.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const answers = Array.from(this.questions.children).map((el, idx) => {
|
const answers = Array.from(this.questions.children).map((el, idx) => {
|
||||||
const input = (el.firstElementChild as HTMLInputElement);
|
const input = el.querySelector('input[type="text"]') as HTMLInputElement;
|
||||||
return input.value;
|
return input.value;
|
||||||
}).filter(v => !!v.trim());
|
}).filter(v => !!v.trim());
|
||||||
|
|
||||||
if(answers.length < 2) {
|
if(answers.length < 2) {
|
||||||
toast('Please enter at least two options');
|
toast('Please enter at least two options.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,8 +150,23 @@ export default class PopupCreatePoll extends PopupElement {
|
|||||||
//const randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
|
//const randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
|
||||||
//const randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString();
|
//const randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString();
|
||||||
|
|
||||||
|
const pFlags: Poll['pFlags'] = {};
|
||||||
|
|
||||||
|
if(this.anonymousCheckboxField && !this.anonymousCheckboxField.input.checked) {
|
||||||
|
pFlags.public_voters = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.multipleCheckboxField.input.checked) {
|
||||||
|
pFlags.multiple_choice = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.quizCheckboxField.input.checked) {
|
||||||
|
pFlags.quiz = true;
|
||||||
|
}
|
||||||
|
|
||||||
const poll: Poll = {
|
const poll: Poll = {
|
||||||
_: 'poll',
|
_: 'poll',
|
||||||
|
pFlags,
|
||||||
question,
|
question,
|
||||||
answers: answers.map((value, idx) => {
|
answers: answers.map((value, idx) => {
|
||||||
return {
|
return {
|
||||||
@ -88,17 +179,22 @@ export default class PopupCreatePoll extends PopupElement {
|
|||||||
};
|
};
|
||||||
//poll.id = randomIDS;
|
//poll.id = randomIDS;
|
||||||
|
|
||||||
appMessagesManager.sendOther($rootScope.selectedPeerID, appPollsManager.getInputMediaPoll(poll));
|
const inputMediaPoll = appPollsManager.getInputMediaPoll(poll, this.correctAnswers, this.quizSolutionInput ? this.quizSolutionInput.value : undefined);
|
||||||
|
|
||||||
|
appMessagesManager.sendOther($rootScope.selectedPeerID, inputMediaPoll);
|
||||||
};
|
};
|
||||||
|
|
||||||
onInput = (e: Event) => {
|
onInput = (e: Event) => {
|
||||||
const target = e.target as HTMLInputElement;
|
const target = e.target as HTMLInputElement;
|
||||||
|
|
||||||
|
const radioLabel = findUpTag(target, 'LABEL');
|
||||||
if(target.value.length) {
|
if(target.value.length) {
|
||||||
target.parentElement.classList.add('is-filled');
|
target.parentElement.classList.add('is-filled');
|
||||||
|
radioLabel.classList.remove('hidden-widget');
|
||||||
|
radioLabel.firstElementChild.removeAttribute('disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
const isLast = !target.parentElement.nextElementSibling;
|
const isLast = !radioLabel.nextElementSibling;
|
||||||
if(isLast && target.value.length && this.questions.childElementCount < 10) {
|
if(isLast && target.value.length && this.questions.childElementCount < 10) {
|
||||||
this.appendMoreField();
|
this.appendMoreField();
|
||||||
}
|
}
|
||||||
@ -106,27 +202,44 @@ export default class PopupCreatePoll extends PopupElement {
|
|||||||
|
|
||||||
onDeleteClick = (e: MouseEvent) => {
|
onDeleteClick = (e: MouseEvent) => {
|
||||||
const target = e.target as HTMLSpanElement;
|
const target = e.target as HTMLSpanElement;
|
||||||
target.parentElement.remove();
|
findUpTag(target, 'LABEL').remove();
|
||||||
|
|
||||||
Array.from(this.questions.children).forEach((el, idx) => {
|
Array.from(this.questions.children).forEach((el, idx) => {
|
||||||
const label = el.firstElementChild.nextElementSibling as HTMLLabelElement;
|
const label = el.querySelector('label') as HTMLLabelElement;
|
||||||
label.innerText = 'Option ' + (idx + 1);
|
label.innerText = 'Option ' + (idx + 1);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private appendMoreField() {
|
private appendMoreField() {
|
||||||
|
const tempID = this.tempID++;
|
||||||
const idx = this.questions.childElementCount + 1;
|
const idx = this.questions.childElementCount + 1;
|
||||||
const questionField = InputField('Add an Option', 'Option ' + idx, 'question-' + this.tempID++);
|
const questionField = InputField('Add an Option', 'Option ' + idx, 'question-' + tempID);
|
||||||
(questionField.firstElementChild as HTMLInputElement).addEventListener('input', this.onInput);
|
(questionField.firstElementChild as HTMLInputElement).addEventListener('input', this.onInput);
|
||||||
|
|
||||||
|
const radioField = RadioField('', 'question');
|
||||||
|
radioField.main.append(questionField);
|
||||||
|
radioField.label.classList.add('hidden-widget');
|
||||||
|
radioField.input.disabled = true;
|
||||||
|
if(!this.quizCheckboxField.input.checked) {
|
||||||
|
radioField.label.classList.remove('radio-field');
|
||||||
|
}
|
||||||
|
radioField.input.addEventListener('change', () => {
|
||||||
|
const checked = radioField.input.checked;
|
||||||
|
if(checked) {
|
||||||
|
const idx = whichChild(radioField.label);
|
||||||
|
this.correctAnswers = [new Uint8Array([idx])];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const deleteBtn = document.createElement('span');
|
const deleteBtn = document.createElement('span');
|
||||||
deleteBtn.classList.add('btn-icon', 'tgico-close');
|
deleteBtn.classList.add('btn-icon', 'tgico-close');
|
||||||
questionField.append(deleteBtn);
|
questionField.append(deleteBtn);
|
||||||
|
|
||||||
deleteBtn.addEventListener('click', this.onDeleteClick, {once: true});
|
deleteBtn.addEventListener('click', this.onDeleteClick, {once: true});
|
||||||
|
|
||||||
this.questions.append(questionField);
|
this.questions.append(radioField.label);
|
||||||
|
|
||||||
this.scrollable.scrollTo(this.scrollable.scrollHeight, 'top', true, true);
|
this.scrollable.scrollIntoView(this.questions.lastElementChild as HTMLElement, true);
|
||||||
|
//this.scrollable.scrollTo(this.scrollable.scrollHeight, 'top', true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
18
src/components/radioField.ts
Normal file
18
src/components/radioField.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const RadioField = (text: string, name: string) => {
|
||||||
|
const label = document.createElement('label');
|
||||||
|
label.classList.add('radio-field');
|
||||||
|
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.type = 'radio';
|
||||||
|
input.id = input.name = 'input-radio-' + name;
|
||||||
|
|
||||||
|
const main = document.createElement('div');
|
||||||
|
main.classList.add('radio-field-main');
|
||||||
|
main.innerText = text;
|
||||||
|
|
||||||
|
label.append(input, main);
|
||||||
|
|
||||||
|
return {label, input, main};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RadioField;
|
@ -667,9 +667,9 @@ export class AppMessagesManager {
|
|||||||
noWebPage: true,
|
noWebPage: true,
|
||||||
newMedia: any
|
newMedia: any
|
||||||
}> = {}) {
|
}> = {}) {
|
||||||
if(!this.canEditMessage(messageID)) {
|
/* if(!this.canEditMessage(messageID)) {
|
||||||
return Promise.reject({type: 'MESSAGE_EDIT_FORBIDDEN'});
|
return Promise.reject({type: 'MESSAGE_EDIT_FORBIDDEN'});
|
||||||
}
|
} */
|
||||||
|
|
||||||
if(messageID < 0) {
|
if(messageID < 0) {
|
||||||
if(this.tempFinalizeCallbacks[messageID] === undefined) {
|
if(this.tempFinalizeCallbacks[messageID] === undefined) {
|
||||||
@ -2397,8 +2397,6 @@ export class AppMessagesManager {
|
|||||||
apiMessage.totalEntities = RichTextProcessor.mergeEntities(myEntities, apiEntities, !apiMessage.pending);
|
apiMessage.totalEntities = RichTextProcessor.mergeEntities(myEntities, apiEntities, !apiMessage.pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
apiMessage.canBeEdited = this.canMessageBeEdited(apiMessage);
|
|
||||||
|
|
||||||
if(!options.isEdited) {
|
if(!options.isEdited) {
|
||||||
this.messagesStorage[mid] = apiMessage;
|
this.messagesStorage[mid] = apiMessage;
|
||||||
(this.messagesStorageByPeerID[peerID] ?? (this.messagesStorageByPeerID[peerID] = {}))[mid] = apiMessage;
|
(this.messagesStorageByPeerID[peerID] ?? (this.messagesStorageByPeerID[peerID] = {}))[mid] = apiMessage;
|
||||||
@ -2588,15 +2586,18 @@ export class AppMessagesManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public canMessageBeEdited(message: any) {
|
public canMessageBeEdited(message: any, kind: 'text' | 'poll') {
|
||||||
const goodMedias = [
|
const goodMedias = [
|
||||||
'messageMediaPhoto',
|
'messageMediaPhoto',
|
||||||
'messageMediaDocument',
|
'messageMediaDocument',
|
||||||
'messageMediaWebPage',
|
'messageMediaWebPage',
|
||||||
'messageMediaPending',
|
'messageMediaPending'
|
||||||
'messageMediaPoll'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if(kind == 'poll') {
|
||||||
|
goodMedias.push('messageMediaPoll');
|
||||||
|
}
|
||||||
|
|
||||||
if(message._ != 'message' ||
|
if(message._ != 'message' ||
|
||||||
message.deleted ||
|
message.deleted ||
|
||||||
message.fwd_from ||
|
message.fwd_from ||
|
||||||
@ -2615,13 +2616,13 @@ export class AppMessagesManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public canEditMessage(messageID: number) {
|
public canEditMessage(messageID: number, kind: 'text' | 'poll' = 'text') {
|
||||||
if(!this.messagesStorage[messageID]) {
|
if(!this.messagesStorage[messageID]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const message = this.messagesStorage[messageID];
|
const message = this.messagesStorage[messageID];
|
||||||
if(!message || !message.canBeEdited) {
|
if(!message || !this.canMessageBeEdited(message, kind)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { InputMedia } from "../../layer";
|
||||||
import { logger, LogLevels } from "../logger";
|
import { logger, LogLevels } from "../logger";
|
||||||
import apiManager from "../mtproto/mtprotoworker";
|
import apiManager from "../mtproto/mtprotoworker";
|
||||||
import { MOUNT_CLASS_TO } from "../mtproto/mtproto_config";
|
import { MOUNT_CLASS_TO } from "../mtproto/mtproto_config";
|
||||||
@ -140,10 +141,19 @@ class AppPollsManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getInputMediaPoll(poll: Poll) {
|
public getInputMediaPoll(poll: Poll, correctAnswers?: Uint8Array[], solution?: string): InputMedia.inputMediaPoll {
|
||||||
|
let solution_entities: any[];
|
||||||
|
if(solution) {
|
||||||
|
solution_entities = [];
|
||||||
|
solution = RichTextProcessor.parseMarkdown(solution, solution_entities);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_: 'inputMediaPoll',
|
_: 'inputMediaPoll',
|
||||||
poll
|
poll,
|
||||||
|
correct_answers: correctAnswers,
|
||||||
|
solution,
|
||||||
|
solution_entities
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radio-field {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden-widget, .radio-field:first-child:last-child {
|
||||||
|
.btn-icon {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.input-field {
|
.input-field {
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
.btn-icon {
|
.btn-icon {
|
||||||
@ -19,13 +30,6 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity .2s ease;
|
transition: opacity .2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.is-filled), &:first-child:last-child {
|
|
||||||
.btn-icon {
|
|
||||||
pointer-events: none;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* &:last-child:not(:nth-child(10)) {
|
/* &:last-child:not(:nth-child(10)) {
|
||||||
.btn-icon {
|
.btn-icon {
|
||||||
display: none;
|
display: none;
|
||||||
@ -36,14 +40,24 @@
|
|||||||
.caption {
|
.caption {
|
||||||
color: #707579;
|
color: #707579;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
padding: 16px 24px 0;
|
padding: 1rem 1.5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.poll-create-questions {
|
.poll-create-questions {
|
||||||
padding: 0px 20px 32.5px;
|
padding: 0px 1.25rem 2.03125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.poll-create-settings {
|
||||||
|
padding: 0 .5rem .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
border-bottom: 1px solid #edeff1;
|
border-bottom: 1px solid #edeff1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
margin-top: .875rem;
|
||||||
|
font-size: .875rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
}
|
}
|
@ -72,6 +72,7 @@ $floating-left-sidebar: 925px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
--z-below: -1;
|
||||||
--color-gray: #c4c9cc;
|
--color-gray: #c4c9cc;
|
||||||
--color-gray-hover: rgba(112, 117, 121, .08);
|
--color-gray-hover: rgba(112, 117, 121, .08);
|
||||||
--layer-transition: .2s ease-in-out;
|
--layer-transition: .2s ease-in-out;
|
||||||
@ -675,7 +676,7 @@ hr {
|
|||||||
margin: 1.25rem 0;
|
margin: 1.25rem 0;
|
||||||
display: block;
|
display: block;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 0 18px;
|
padding: 0 1.125rem;
|
||||||
/* font-weight: 500; */
|
/* font-weight: 500; */
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@ -684,23 +685,138 @@ hr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[type="checkbox"] {
|
.radio-field {
|
||||||
position: absolute;
|
display: block;
|
||||||
opacity: 0;
|
position: relative;
|
||||||
pointer-events: none;
|
padding-left: 3.5rem;
|
||||||
-webkit-box-sizing: border-box;
|
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;
|
box-sizing: border-box;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: var(--z-below);
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type="checkbox"] {
|
||||||
& + span {
|
& + span {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: calc(18px + 2.25rem);
|
padding-left: 3.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
line-height: 25px;
|
line-height: 25px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
transition: .2s opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
&: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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[type="checkbox"] {
|
||||||
|
& + span {
|
||||||
&:before, &:after {
|
&:before, &:after {
|
||||||
content: '';
|
content: '';
|
||||||
left: 0;
|
left: 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user