First design iteration of device verification dialogs
This commit is contained in:
parent
7f3d97517f
commit
488cc5e73b
392
resources/qml/device-verification/DeviceVerification.qml
Normal file
392
resources/qml/device-verification/DeviceVerification.qml
Normal file
@ -0,0 +1,392 @@
|
|||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 2.10
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
import QtQuick.Layouts 1.10
|
||||||
|
|
||||||
|
Window {
|
||||||
|
title: stack.currentItem.title
|
||||||
|
id: dialog
|
||||||
|
|
||||||
|
flags: Qt.Dialog
|
||||||
|
|
||||||
|
|
||||||
|
height: stack.implicitHeight
|
||||||
|
width: stack.implicitWidth
|
||||||
|
StackView {
|
||||||
|
id: stack
|
||||||
|
initialItem: newVerificationRequest
|
||||||
|
implicitWidth: currentItem.implicitWidth
|
||||||
|
implicitHeight: currentItem.implicitHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosing: stack.replace(newVerificationRequest)
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: newVerificationRequest
|
||||||
|
Pane {
|
||||||
|
property string title: "Device Verification Request"
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: "A new device was added."
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: "The device may have been added by you signing in from another client or physical device. To ensure that no malicious user can eavesdrop on your encrypted communications, you should verify the new device."
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
text: "Cancel"
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: "Start verification"
|
||||||
|
onClicked: stack.replace(awaitingVerificationRequestAccept)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: awaitingVerificationRequestAccept
|
||||||
|
Pane {
|
||||||
|
property string title: "Waiting for other party"
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
id: content
|
||||||
|
text: "Waiting for other side to accept the verification request."
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
text: "Cancel"
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
// temporary, until it is bound to a backend
|
||||||
|
interval: 5000; running: true;
|
||||||
|
onTriggered: if (Math.random() > 0.5) stack.replace(emojiVerification); else stack.replace(digitVerification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: digitVerification
|
||||||
|
Pane {
|
||||||
|
property string title: "Verification Code"
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: "Please verify the following digits. You should see the same numbers on both sides. If they differ, please press 'They do not match!' to abort verification!"
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Text {
|
||||||
|
font.pixelSize: Qt.application.font.pixelSize * 2
|
||||||
|
text: "1234"
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
font.pixelSize: Qt.application.font.pixelSize * 2
|
||||||
|
text: "1234"
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
font.pixelSize: Qt.application.font.pixelSize * 2
|
||||||
|
text: "1234"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
text: "They do not match!"
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: "They match."
|
||||||
|
onClicked: stack.replace(awaitingVerificationConfirmation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: emojiVerification
|
||||||
|
Pane {
|
||||||
|
property string title: "Verification Code"
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
text: "Please verify the following emoji. You should see the same emoji on both sides. If they differ, please press 'They do not match!' to abort verification!"
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
id: emojis
|
||||||
|
|
||||||
|
property var mapping: [
|
||||||
|
{"number": 0, "emoji": "πΆ", "description": "Dog", "unicode": "U+1F436"},
|
||||||
|
{"number": 1, "emoji": "π±", "description": "Cat", "unicode": "U+1F431"},
|
||||||
|
{"number": 2, "emoji": "π¦", "description": "Lion", "unicode": "U+1F981"},
|
||||||
|
{"number": 3, "emoji": "π", "description": "Horse", "unicode": "U+1F40E"},
|
||||||
|
{"number": 4, "emoji": "π¦", "description": "Unicorn", "unicode": "U+1F984"},
|
||||||
|
{"number": 5, "emoji": "π·", "description": "Pig", "unicode": "U+1F437"},
|
||||||
|
{"number": 6, "emoji": "π", "description": "Elephant", "unicode": "U+1F418"},
|
||||||
|
{"number": 7, "emoji": "π°", "description": "Rabbit", "unicode": "U+1F430"},
|
||||||
|
{"number": 8, "emoji": "πΌ", "description": "Panda", "unicode": "U+1F43C"},
|
||||||
|
{"number": 9, "emoji": "π", "description": "Rooster", "unicode": "U+1F413"},
|
||||||
|
{"number": 10, "emoji": "π§", "description": "Penguin", "unicode": "U+1F427"},
|
||||||
|
{"number": 11, "emoji": "π’", "description": "Turtle", "unicode": "U+1F422"},
|
||||||
|
{"number": 12, "emoji": "π", "description": "Fish", "unicode": "U+1F41F"},
|
||||||
|
{"number": 13, "emoji": "π", "description": "Octopus", "unicode": "U+1F419"},
|
||||||
|
{"number": 14, "emoji": "π¦", "description": "Butterfly", "unicode": "U+1F98B"},
|
||||||
|
{"number": 15, "emoji": "π·", "description": "Flower", "unicode": "U+1F337"},
|
||||||
|
{"number": 16, "emoji": "π³", "description": "Tree", "unicode": "U+1F333"},
|
||||||
|
{"number": 17, "emoji": "π΅", "description": "Cactus", "unicode": "U+1F335"},
|
||||||
|
{"number": 18, "emoji": "π", "description": "Mushroom", "unicode": "U+1F344"},
|
||||||
|
{"number": 19, "emoji": "π", "description": "Globe", "unicode": "U+1F30F"},
|
||||||
|
{"number": 20, "emoji": "π", "description": "Moon", "unicode": "U+1F319"},
|
||||||
|
{"number": 21, "emoji": "βοΈ", "description": "Cloud", "unicode": "U+2601U+FE0F"},
|
||||||
|
{"number": 22, "emoji": "π₯", "description": "Fire", "unicode": "U+1F525"},
|
||||||
|
{"number": 23, "emoji": "π", "description": "Banana", "unicode": "U+1F34C"},
|
||||||
|
{"number": 24, "emoji": "π", "description": "Apple", "unicode": "U+1F34E"},
|
||||||
|
{"number": 25, "emoji": "π", "description": "Strawberry", "unicode": "U+1F353"},
|
||||||
|
{"number": 26, "emoji": "π½", "description": "Corn", "unicode": "U+1F33D"},
|
||||||
|
{"number": 27, "emoji": "π", "description": "Pizza", "unicode": "U+1F355"},
|
||||||
|
{"number": 28, "emoji": "π", "description": "Cake", "unicode": "U+1F382"},
|
||||||
|
{"number": 29, "emoji": "β€οΈ", "description": "Heart", "unicode": "U+2764U+FE0F"},
|
||||||
|
{"number": 30, "emoji": "π", "description": "Smiley", "unicode": "U+1F600"},
|
||||||
|
{"number": 31, "emoji": "π€", "description": "Robot", "unicode": "U+1F916"},
|
||||||
|
{"number": 32, "emoji": "π©", "description": "Hat", "unicode": "U+1F3A9"},
|
||||||
|
{"number": 33, "emoji": "π", "description": "Glasses", "unicode": "U+1F453"},
|
||||||
|
{"number": 34, "emoji": "π§", "description": "Spanner", "unicode": "U+1F527"},
|
||||||
|
{"number": 35, "emoji": "π
", "description": "Santa", "unicode": "U+1F385"},
|
||||||
|
{"number": 36, "emoji": "π", "description": "Thumbs Up", "unicode": "U+1F44D"},
|
||||||
|
{"number": 37, "emoji": "βοΈ", "description": "Umbrella", "unicode": "U+2602U+FE0F"},
|
||||||
|
{"number": 38, "emoji": "β", "description": "Hourglass", "unicode": "U+231B"},
|
||||||
|
{"number": 39, "emoji": "β°", "description": "Clock", "unicode": "U+23F0"},
|
||||||
|
{"number": 40, "emoji": "π", "description": "Gift", "unicode": "U+1F381"},
|
||||||
|
{"number": 41, "emoji": "π‘", "description": "Light Bulb", "unicode": "U+1F4A1"},
|
||||||
|
{"number": 42, "emoji": "π", "description": "Book", "unicode": "U+1F4D5"},
|
||||||
|
{"number": 43, "emoji": "βοΈ", "description": "Pencil", "unicode": "U+270FU+FE0F"},
|
||||||
|
{"number": 44, "emoji": "π", "description": "Paperclip", "unicode": "U+1F4CE"},
|
||||||
|
{"number": 45, "emoji": "βοΈ", "description": "Scissors", "unicode": "U+2702U+FE0F"},
|
||||||
|
{"number": 46, "emoji": "π", "description": "Lock", "unicode": "U+1F512"},
|
||||||
|
{"number": 47, "emoji": "π", "description": "Key", "unicode": "U+1F511"},
|
||||||
|
{"number": 48, "emoji": "π¨", "description": "Hammer", "unicode": "U+1F528"},
|
||||||
|
{"number": 49, "emoji": "βοΈ", "description": "Telephone", "unicode": "U+260EU+FE0F"},
|
||||||
|
{"number": 50, "emoji": "π", "description": "Flag", "unicode": "U+1F3C1"},
|
||||||
|
{"number": 51, "emoji": "π", "description": "Train", "unicode": "U+1F682"},
|
||||||
|
{"number": 52, "emoji": "π²", "description": "Bicycle", "unicode": "U+1F6B2"},
|
||||||
|
{"number": 53, "emoji": "βοΈ", "description": "Aeroplane", "unicode": "U+2708U+FE0F"},
|
||||||
|
{"number": 54, "emoji": "π", "description": "Rocket", "unicode": "U+1F680"},
|
||||||
|
{"number": 55, "emoji": "π", "description": "Trophy", "unicode": "U+1F3C6"},
|
||||||
|
{"number": 56, "emoji": "β½", "description": "Ball", "unicode": "U+26BD"},
|
||||||
|
{"number": 57, "emoji": "πΈ", "description": "Guitar", "unicode": "U+1F3B8"},
|
||||||
|
{"number": 58, "emoji": "πΊ", "description": "Trumpet", "unicode": "U+1F3BA"},
|
||||||
|
{"number": 59, "emoji": "π", "description": "Bell", "unicode": "U+1F514"},
|
||||||
|
{"number": 60, "emoji": "β", "description": "Anchor", "unicode": "U+2693"},
|
||||||
|
{"number": 61, "emoji": "π§", "description": "Headphones", "unicode": "U+1F3A7"},
|
||||||
|
{"number": 62, "emoji": "π", "description": "Folder", "unicode": "U+1F4C1"},
|
||||||
|
{"number": 63, "emoji": "π", "description": "Pin", "unicode": "U+1F4CC"}
|
||||||
|
]
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
|
model: 7
|
||||||
|
delegate: Rectangle {
|
||||||
|
color: "red"
|
||||||
|
implicitHeight: Qt.application.font.pixelSize * 8
|
||||||
|
implicitWidth: col.width
|
||||||
|
ColumnLayout {
|
||||||
|
id: col
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
property var emoji: emojis.mapping[Math.floor(Math.random()*64)]
|
||||||
|
Text {
|
||||||
|
height: font.pixelSize * 2
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: col.emoji.emoji
|
||||||
|
font.pixelSize: Qt.application.font.pixelSize * 4
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||||
|
text: col.emoji.description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
text: "They do not match!"
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: "They match."
|
||||||
|
onClicked: stack.replace(awaitingVerificationConfirmation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: awaitingVerificationConfirmation
|
||||||
|
Pane {
|
||||||
|
property string title: "Awaiting Confirmation"
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
id: content
|
||||||
|
text: "Waiting for other side to complete verification."
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
text: "Cancel"
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
// temporary, until it is bound to a backend
|
||||||
|
interval: 5000; running: true;
|
||||||
|
onTriggered: Math.random() > 0.5 ? stack.replace(verificationSuccess) : stack.replace(partnerAborted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: verificationSuccess
|
||||||
|
Pane {
|
||||||
|
property string title: "Successful Verification"
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
id: content
|
||||||
|
text: "Verification successful! Both sides verified their devices!"
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: "Close"
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: partnerAborted
|
||||||
|
Pane {
|
||||||
|
property string title: "Verification aborted!"
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 16
|
||||||
|
Text {
|
||||||
|
Layout.maximumWidth: 400
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
id: content
|
||||||
|
text: "Verification canceled by the other party!"
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
text: "Close"
|
||||||
|
onClicked: dialog.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
resources/qml/device-verification/DeviceVerificationTest.qml
Normal file
13
resources/qml/device-verification/DeviceVerificationTest.qml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import QtQuick 2.3
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
Item {
|
||||||
|
DeviceVerification {
|
||||||
|
id: deviceVerification
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Test DeviceVerification"
|
||||||
|
onClicked: deviceVerification.show()
|
||||||
|
}
|
||||||
|
}
|
66
resources/qml/device-verification/sas-emoji.json
Normal file
66
resources/qml/device-verification/sas-emoji.json
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
[
|
||||||
|
{"number": 0, "emoji": "πΆ", "description": "Dog", "unicode": "U+1F436"},
|
||||||
|
{"number": 1, "emoji": "π±", "description": "Cat", "unicode": "U+1F431"},
|
||||||
|
{"number": 2, "emoji": "π¦", "description": "Lion", "unicode": "U+1F981"},
|
||||||
|
{"number": 3, "emoji": "π", "description": "Horse", "unicode": "U+1F40E"},
|
||||||
|
{"number": 4, "emoji": "π¦", "description": "Unicorn", "unicode": "U+1F984"},
|
||||||
|
{"number": 5, "emoji": "π·", "description": "Pig", "unicode": "U+1F437"},
|
||||||
|
{"number": 6, "emoji": "π", "description": "Elephant", "unicode": "U+1F418"},
|
||||||
|
{"number": 7, "emoji": "π°", "description": "Rabbit", "unicode": "U+1F430"},
|
||||||
|
{"number": 8, "emoji": "πΌ", "description": "Panda", "unicode": "U+1F43C"},
|
||||||
|
{"number": 9, "emoji": "π", "description": "Rooster", "unicode": "U+1F413"},
|
||||||
|
{"number": 10, "emoji": "π§", "description": "Penguin", "unicode": "U+1F427"},
|
||||||
|
{"number": 11, "emoji": "π’", "description": "Turtle", "unicode": "U+1F422"},
|
||||||
|
{"number": 12, "emoji": "π", "description": "Fish", "unicode": "U+1F41F"},
|
||||||
|
{"number": 13, "emoji": "π", "description": "Octopus", "unicode": "U+1F419"},
|
||||||
|
{"number": 14, "emoji": "π¦", "description": "Butterfly", "unicode": "U+1F98B"},
|
||||||
|
{"number": 15, "emoji": "π·", "description": "Flower", "unicode": "U+1F337"},
|
||||||
|
{"number": 16, "emoji": "π³", "description": "Tree", "unicode": "U+1F333"},
|
||||||
|
{"number": 17, "emoji": "π΅", "description": "Cactus", "unicode": "U+1F335"},
|
||||||
|
{"number": 18, "emoji": "π", "description": "Mushroom", "unicode": "U+1F344"},
|
||||||
|
{"number": 19, "emoji": "π", "description": "Globe", "unicode": "U+1F30F"},
|
||||||
|
{"number": 20, "emoji": "π", "description": "Moon", "unicode": "U+1F319"},
|
||||||
|
{"number": 21, "emoji": "βοΈ", "description": "Cloud", "unicode": "U+2601U+FE0F"},
|
||||||
|
{"number": 22, "emoji": "π₯", "description": "Fire", "unicode": "U+1F525"},
|
||||||
|
{"number": 23, "emoji": "π", "description": "Banana", "unicode": "U+1F34C"},
|
||||||
|
{"number": 24, "emoji": "π", "description": "Apple", "unicode": "U+1F34E"},
|
||||||
|
{"number": 25, "emoji": "π", "description": "Strawberry", "unicode": "U+1F353"},
|
||||||
|
{"number": 26, "emoji": "π½", "description": "Corn", "unicode": "U+1F33D"},
|
||||||
|
{"number": 27, "emoji": "π", "description": "Pizza", "unicode": "U+1F355"},
|
||||||
|
{"number": 28, "emoji": "π", "description": "Cake", "unicode": "U+1F382"},
|
||||||
|
{"number": 29, "emoji": "β€οΈ", "description": "Heart", "unicode": "U+2764U+FE0F"},
|
||||||
|
{"number": 30, "emoji": "π", "description": "Smiley", "unicode": "U+1F600"},
|
||||||
|
{"number": 31, "emoji": "π€", "description": "Robot", "unicode": "U+1F916"},
|
||||||
|
{"number": 32, "emoji": "π©", "description": "Hat", "unicode": "U+1F3A9"},
|
||||||
|
{"number": 33, "emoji": "π", "description": "Glasses", "unicode": "U+1F453"},
|
||||||
|
{"number": 34, "emoji": "π§", "description": "Spanner", "unicode": "U+1F527"},
|
||||||
|
{"number": 35, "emoji": "π
", "description": "Santa", "unicode": "U+1F385"},
|
||||||
|
{"number": 36, "emoji": "π", "description": "Thumbs Up", "unicode": "U+1F44D"},
|
||||||
|
{"number": 37, "emoji": "βοΈ", "description": "Umbrella", "unicode": "U+2602U+FE0F"},
|
||||||
|
{"number": 38, "emoji": "β", "description": "Hourglass", "unicode": "U+231B"},
|
||||||
|
{"number": 39, "emoji": "β°", "description": "Clock", "unicode": "U+23F0"},
|
||||||
|
{"number": 40, "emoji": "π", "description": "Gift", "unicode": "U+1F381"},
|
||||||
|
{"number": 41, "emoji": "π‘", "description": "Light Bulb", "unicode": "U+1F4A1"},
|
||||||
|
{"number": 42, "emoji": "π", "description": "Book", "unicode": "U+1F4D5"},
|
||||||
|
{"number": 43, "emoji": "βοΈ", "description": "Pencil", "unicode": "U+270FU+FE0F"},
|
||||||
|
{"number": 44, "emoji": "π", "description": "Paperclip", "unicode": "U+1F4CE"},
|
||||||
|
{"number": 45, "emoji": "βοΈ", "description": "Scissors", "unicode": "U+2702U+FE0F"},
|
||||||
|
{"number": 46, "emoji": "π", "description": "Lock", "unicode": "U+1F512"},
|
||||||
|
{"number": 47, "emoji": "π", "description": "Key", "unicode": "U+1F511"},
|
||||||
|
{"number": 48, "emoji": "π¨", "description": "Hammer", "unicode": "U+1F528"},
|
||||||
|
{"number": 49, "emoji": "βοΈ", "description": "Telephone", "unicode": "U+260EU+FE0F"},
|
||||||
|
{"number": 50, "emoji": "π", "description": "Flag", "unicode": "U+1F3C1"},
|
||||||
|
{"number": 51, "emoji": "π", "description": "Train", "unicode": "U+1F682"},
|
||||||
|
{"number": 52, "emoji": "π²", "description": "Bicycle", "unicode": "U+1F6B2"},
|
||||||
|
{"number": 53, "emoji": "βοΈ", "description": "Aeroplane", "unicode": "U+2708U+FE0F"},
|
||||||
|
{"number": 54, "emoji": "π", "description": "Rocket", "unicode": "U+1F680"},
|
||||||
|
{"number": 55, "emoji": "π", "description": "Trophy", "unicode": "U+1F3C6"},
|
||||||
|
{"number": 56, "emoji": "β½", "description": "Ball", "unicode": "U+26BD"},
|
||||||
|
{"number": 57, "emoji": "πΈ", "description": "Guitar", "unicode": "U+1F3B8"},
|
||||||
|
{"number": 58, "emoji": "πΊ", "description": "Trumpet", "unicode": "U+1F3BA"},
|
||||||
|
{"number": 59, "emoji": "π", "description": "Bell", "unicode": "U+1F514"},
|
||||||
|
{"number": 60, "emoji": "β", "description": "Anchor", "unicode": "U+2693"},
|
||||||
|
{"number": 61, "emoji": "π§", "description": "Headphones", "unicode": "U+1F3A7"},
|
||||||
|
{"number": 62, "emoji": "π", "description": "Folder", "unicode": "U+1F4C1"},
|
||||||
|
{"number": 63, "emoji": "π", "description": "Pin", "unicode": "U+1F4CC"}
|
||||||
|
]
|
Loadingβ¦
Reference in New Issue
Block a user