Created
February 26, 2021 06:12
-
-
Save abbabaa/59fea53e8251148aff470f9fe79d0f56 to your computer and use it in GitHub Desktop.
Discord Bot Site - Paragon - Made for Phineas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#header | |
.logo-network | |
.logo | |
.logo-github | |
#demo | |
.title The last Discord bot you'll ever need. | |
.invite-now-wrapper | |
.invite-now Invite Now | |
.discord-app-mount | |
.discord-app | |
.app-buttons | |
.guilds | |
.guild.selected(style="background-image: url(https://alca.tv/static/codepen/pens/zEXwQM/Para-GuildIcon.png)") | |
.guild | |
.guild.guild-add | |
.channels | |
.header Server Name | |
.channel-wrapper | |
.user | |
.chat | |
.header | |
| general | |
.messages-wrapper | |
.messages | |
.input-wrapper | |
.input | |
textarea(placeholder="Message #general" disabled) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const demoEle = { lastMsgGroup: null }; | |
const users = { | |
phineas: { | |
username: 'Phineas', | |
nameColor: 'hsl(345, 50%, 52%)', | |
avatar: 'https://cdn.discordapp.com/avatars/94490510688792576/a_46a9fccf4764d0311943d875cdc07128.webp?size=128' | |
}, | |
paragon: { | |
username: 'Paragon', | |
nameColor: 'hsl(212, 51%, 59%)', | |
bot: true, | |
avatar: 'https://cdn.discordapp.com/avatars/273591274899111937/fe783607823a2028988b1a4bc26cfe3e.webp?size=128' | |
} | |
}; | |
const channelData = [ | |
{ | |
name: 'general', | |
selected: true, | |
messages: [ | |
{ | |
type: 'input', | |
text: '>help', | |
user: users.phineas | |
}, { | |
type: 'message', | |
delay: 350, | |
user: users.paragon, | |
embedData: { | |
title: '-=-=-=-=-= Help =-=-=-=-=-', | |
pill: 'hsl(202, 35%, 68%)', | |
thumb: null, | |
fields: [ | |
{ | |
name: '-> Paragon', | |
value: 'help, info, invite, shard, proxy, stats, ping' | |
}, { | |
name: '-> Lookup/Utility', | |
value: 'socialblade, snapcode, image, translate, langdetect, github, twitter, ipinfo, calculate, btcprice' | |
}, { | |
name: '-> Fun', | |
value: 'cat, dog, birb, 8ball, trigger, urbandictionary' | |
}, { | |
name: '-> Minecraft', | |
value: 'mcserver, badlionstats, hypixelstats, hivestats' | |
}, { | |
name: '-> Music', | |
value: 'play, skip, queue, pause, volume, resume, lyricsample' | |
}, { | |
name: '-> Management', | |
value: 'beta, guser, deploy-git-release, datasearch, dbstats, add-shard, sAnnounce, reqinv, add-zone-record, get-msg' | |
} | |
] | |
} | |
} | |
] | |
}, { | |
name: 'music', | |
messages: [ | |
{ | |
type: 'input', | |
text: '>play trap nation', | |
user: users.phineas | |
}, { | |
type: 'message', | |
delay: 350, | |
user: users.paragon, | |
text: '[emoji id="1f5d2"] Queued: Trap Nation: 2018 Best Trap Music', | |
embedData: { | |
title: '-=-=-=-=-= Music =-=-=-=-=-', | |
pill: 'hsl(202, 35%, 68%)', | |
thumb: 'https://images-ext-2.discordapp.net/external/Zdj-EIYZixh-NSFIQrmwLq6wn8RjzwEk4Hebb--Mryk/https/i.ytimg.com/vi/KOgvA98FifU/hqdefault.jpg?width=80&height=60', | |
fields: [ | |
{ | |
name: 'Now Streaming', | |
value: 'Trap Nation: 2018 Best Trap Music' | |
}, { | |
name: 'Duration', | |
value: '02:26:33' | |
}, { | |
name: 'Channel', | |
value: 'Uploaded by [strong text="Trap Nation"]' | |
} | |
], | |
footerIcon: users.phineas.avatar, | |
footer: `Requested By ${users.phineas.username}` | |
} | |
}, /*{ | |
type: 'message', | |
delay: 350, | |
user: users.paragon, | |
text: '', | |
embedData: { | |
title: '<Github - AlcaDesign>', | |
pill: 'hsl(0, 0%, 0%)', | |
thumb: 'https://images-ext-2.discordapp.net/external/XQMiC9Ck9IBfIwTh-Vf89Wi8CsAdgWCcZ2-7VYW4nh8/%3Fv%3D4/https/avatars2.githubusercontent.com/u/7132646?width=80&height=80', | |
fields: [ | |
{ | |
name: 'User', | |
value: `[emoji id="1F6E1"] ID: [strong text="#7132646"] | |
[emoji id="1F5FA"] Location: [strong text="United States"] | |
[emoji id="1F5E8"] Bio: [strong text="For all of your digital needs. Creator of Alcabot."] | |
-> Hireable [emoji id="2705"]` | |
}, { | |
name: 'Public Repos', | |
value: '48', | |
inline: true | |
}, { | |
name: 'Followers', | |
value: '33', | |
inline: true | |
}, { | |
name: 'Following', | |
value: '10' | |
} | |
], | |
footer: 'Account Created -> 2014-04-01T22:58:53Z' | |
} | |
}*/ | |
] | |
} | |
]; | |
const bracketsReplaceRegex = /\[(\S*)\s?(.*?)?\]/g; | |
const bracketsSplitRegex = /([^"\s]+)|("[^"]*")/g; | |
const numberTestRegex = /^[\d.]+$/g; | |
let canAddMessages = true; | |
let currentlyLoading = false; | |
let currentChannel = null; | |
function delay(time = 0) { | |
if(!time) { | |
return Promise.resolve(); | |
} | |
return new Promise(resolve => setTimeout(resolve, time)); | |
} | |
function errorHandle(err) { | |
if(err instanceof Error) { | |
console.log(err); | |
} | |
} | |
function clearInput() { | |
demoEle.input.value = ''; | |
} | |
function typeInMessage(text) { | |
let prom = Promise.resolve(); | |
for(let i = 0; i < text.length; i++) { | |
prom = prom.then(() => delay(50 + Math.random() * 35)) | |
.then(() => demoEle.input.value += text[i]); | |
} | |
return prom; | |
} | |
function clearMessages() { | |
if(!canAddMessages || demoEle.lastMsgGroup === null) { | |
return Promise.resolve(); | |
} | |
demoEle.lastMsgGroup = null; | |
canAddMessages = false; | |
demoEle.messages.classList.add('hide'); | |
return delay(300) | |
.then(() => { | |
demoEle.messages.innerHTML = ''; | |
demoEle.messages.classList.remove('hide'); | |
canAddMessages = true; | |
}); | |
} | |
function scrollMessages() { | |
let startY = demoEle.messagesWrapper.scrollTop; | |
let endY = demoEle.messages.scrollHeight - demoEle.messagesWrapper.clientHeight; | |
demoEle.messagesWrapper.scroll({ top: endY, left: 0, behavior: 'smooth' }); | |
} | |
function createEmbed(embed, embedData) { | |
let { | |
title: titleText = '', | |
pill: pillColor = 'hsl(0, 0%, 50%)', | |
footerIcon: footerIconURL = '', | |
footer: footerText = '', | |
thumb: thumbURL = null, | |
fields: fieldList = [] | |
} = embedData; | |
let pill = createElement({ classes: 'embed-pill', parent: embed, style: { backgroundColor: pillColor } }); | |
let rich = createElement({ classes: 'embed-rich', parent: embed }); | |
let content = createElement({ classes: 'embed-content', parent: rich }); | |
let footerContainer = createElement({ parent: rich, style: { height: footerText ? '18px' : '0px' } }); | |
let footerIcon = createElement({ tagName: 'img', classes: 'embed-footer-icon', attrs: { width: 20, height: 20 } }); | |
if(footerIconURL) { | |
footerIcon.onload = () => (footerIcon.width = footerIcon.naturalWidth, footerIcon.height = footerIcon.naturalHeight); | |
footerIcon.src = footerIconURL; | |
footerContainer.appendChild(footerIcon); | |
} | |
let footer = createElement({ tagName: 'span', classes: 'embed-footer', parent: footerContainer, text: footerText }); | |
let innerContent = createElement({ classes: 'embed-inner-content', parent: content }); | |
let thumb = createElement({ tagName: 'img', classes: 'embed-thumb', attrs: { width: 80, height: 80 } }); | |
let title = createElement({ classes: 'embed-title', parent: innerContent, text: titleText }); | |
let fields = createElement({ classes: 'embed-fields', parent: innerContent }); | |
if(thumbURL) { | |
thumb.onload = () => (thumb.width = thumb.naturalWidth, thumb.height = thumb.naturalHeight); | |
thumb.src = thumbURL; | |
content.appendChild(thumb); | |
} | |
if(fieldList.length) { | |
fieldList.forEach(({ name, value, inline }) => { | |
let fieldClasses = [ 'embed-field' ]; | |
if(inline) { | |
fieldClasses.push('embed-field-inline'); | |
} | |
let field = createElement({ classes: fieldClasses, parent: fields }); | |
let nameEle = createElement({ classes: 'embed-field-name', parent: field, text: name }); | |
let valueEle = createElement({ classes: 'embed-field-value', parent: field, text: value }); | |
}); | |
} | |
return { embed, embedData, pill, rich, content, footerContainer, footerIcon, footer, thumb, innerContent, title, fields }; | |
} | |
function createMessageGroup(opts = {}) { | |
let { | |
avatar: avatarUrl = '', | |
username: name = '', | |
nameColor = '', | |
bot = false | |
} = opts; | |
let group = createElement({ classes: 'message-group' }); | |
let avatar = createElement({ classes: 'avatar', parent: group }); | |
let comment = createElement({ classes: 'comment', parent: group }); | |
let usernameWrapper = createElement({ classes: 'username-wrapper', parent: comment }); | |
let username = createElement({ classes: 'username', text: name, parent: usernameWrapper }); | |
let botTag = createElement({ classes: 'bot-tag' }); | |
let date = new Date(); | |
let time = `${date.getHours()}:${('0' + date.getMinutes()).slice(-2)}`; | |
let timestamp = createElement({ classes: 'timestamp', text: 'Today at ' + time, parent: usernameWrapper }); | |
let out = { | |
group, avatar, comment, usernameWrapper, username, timestamp, | |
name, bot, date | |
}; | |
if(bot) { | |
usernameWrapper.appendChild(botTag); | |
out.botTag = botTag; | |
} | |
if(avatarUrl) { | |
avatar.style.backgroundImage = `url(${avatarUrl})`; | |
} | |
if(nameColor) { | |
username.style.color = nameColor; | |
} | |
return out; | |
} | |
function createMessage(opts = {}) { | |
let { text = '', embedData = null } = opts; | |
let message = createElement({ classes: 'message' }); | |
let body = createElement({ classes: 'body', parent: message }); | |
let messageText = createElement({ classes: 'message-text', text, parent: body }); | |
let embed = createElement({ classes: 'embed' }); | |
let embedContent = null; | |
if(embedData) { | |
message.appendChild(embed); | |
embedContent = createEmbed(embed, embedData); | |
} | |
return { message, body, messageText, embed, embedContent }; | |
} | |
function showElement(ele) { | |
ele.classList.add('animate-in'); | |
} | |
function addMessage(opts = {}) { | |
if(!canAddMessages) { | |
console.log('Cannot add message currently'); | |
return Promise.reject(false); | |
} | |
let { | |
username = '', | |
lastMsgGroup = null | |
} = opts; | |
let prom = Promise.resolve(); | |
if(lastMsgGroup === null) { | |
lastMsgGroup = demoEle.lastMsgGroup; | |
if(lastMsgGroup === null || lastMsgGroup.name !== username) { | |
lastMsgGroup = createMessageGroup(opts); | |
demoEle.messages.appendChild(lastMsgGroup.group); | |
demoEle.lastMsgGroup = lastMsgGroup; | |
prom = delay(50) | |
.then(() => showElement(lastMsgGroup.group)); | |
} | |
} | |
let message = createMessage(opts); | |
lastMsgGroup.comment.appendChild(message.message); | |
prom = delay(25) | |
.then(() => { | |
lastMsgGroup.group.style.maxHeight = 'none'; | |
showElement(message.message); | |
setTimeout(scrollMessages, 35); | |
}); | |
} | |
function setChannel(name) { | |
demoEle.channelName.innerText = name; | |
demoEle.input.placeholder = `Message #${name}`; | |
demoEle.channelsList.forEach(n => n.classList.remove('selected')); | |
demoEle.channelsList.find(n => n.innerText === name).classList.add('selected'); | |
return delay(50); | |
} | |
function loadChannel(opts = {}) { | |
let { | |
name = 'general', | |
messages = [] | |
} = opts; | |
if(name === currentChannel || currentlyLoading || !canAddMessages) { | |
return Promise.reject(false); | |
} | |
currentlyLoading = true; | |
currentChannel = name; | |
return setChannel(name) | |
.then(() => clearMessages()) | |
.then(() => delay(200)) | |
.then(() => { | |
let prom = Promise.resolve(); | |
messages.forEach(n => { | |
let { | |
type = 'message', | |
user = { username: 'User' }, | |
text = '', | |
delay: delayTime = 0 | |
} = n; | |
if(type === 'input') { | |
prom = prom.then(() => delay(delayTime)) | |
.then(() => typeInMessage(text)) | |
.then(() => delay(250)) | |
.then(clearInput) | |
.then(() => addMessage(Object.assign({}, user, n))); | |
} | |
else if(type === 'message') { | |
prom = prom.then(() => delay(delayTime)) | |
.then(() => addMessage(Object.assign({}, user, n))); | |
} | |
}); | |
return prom.then(() => currentlyLoading = false); | |
}) | |
} | |
window.addEventListener('load', () => { | |
// Preload avatars | |
Object.values(users).forEach(n => document.createElement('img').src = n.avatar); | |
let root = document.getElementById('demo'); | |
let app = root.querySelector('.discord-app'); | |
let elements = { | |
root, | |
app, | |
invite: '.invite-now', | |
guildName: [ app, '.channels .header' ], | |
channels: [ app, '.channel-wrapper' ], | |
channelName: [ app, '.chat .header' ], | |
messagesWrapper: [ app, '.chat .messages-wrapper' ], | |
messages: [ app, '.chat .messages' ], | |
input: [ app, '.chat .input textarea' ] | |
}; | |
let _ele = Object.keys(elements).reduce((p, key) => { | |
let n = elements[key]; | |
let element = n; | |
if(typeof n === 'string') { | |
element = root.querySelector(n); | |
} | |
else if(Array.isArray(n)) { | |
element = n[0].querySelector(n[1]); | |
} | |
p[key] = element; | |
return p; | |
}, {}); | |
Object.assign(demoEle, _ele); | |
let selectedChannel; | |
channelData.forEach(n => { | |
let { name, selected = false } = n; | |
if(selected) { | |
selectedChannel = n; | |
} | |
n.ele = createElement({ classes: [ 'channel', selected ? 'selected' : '' ], text: name, parent: demoEle.channels }); | |
n.ele.addEventListener('click', () => loadChannel(n).catch(errorHandle)); | |
}); | |
demoEle.channelsList = Array.from(demoEle.channels.children); | |
delay(600).then(() => loadChannel(selectedChannel)).catch(errorHandle); | |
}); | |
function parseBrackets(text) { | |
let changedBrackets = false; | |
let result = text.replace(bracketsReplaceRegex, (match, tag, attributes) => { | |
let attr = {}; | |
if(typeof attributes !== 'number') { | |
attr = attributes.split(bracketsSplitRegex) | |
.filter(n => n && n.trim()) | |
.reduce((p, n) => (n[0] === '"' ? p[p.length - 1] += n : p.push(n), p), []) | |
.map(n => { | |
let spl = n.split(/=/); | |
// if(spl.length === 1) { | |
// } | |
if(numberTestRegex.test(spl[1])) { | |
spl[1] = parseFloat(spl[1]); | |
} | |
else { | |
let m = spl[1].match(/"(.*)"/); | |
if(m !== null && m.length === 2) { | |
spl[1] = m[1]; | |
} | |
} | |
return spl; | |
}) | |
.reduce((p, n) => (p[n[0]] = n[1] || true, p), {}); | |
let ret = null; | |
if(tag === 'emoji') { | |
ret = `<img class="emoji" src="https://twemoji.maxcdn.com/2/svg/${attr.id.toLowerCase()}.svg">`; | |
} | |
else if(tag === 'strong') { | |
ret = `<strong>${attr.text}</strong>`; | |
} | |
if(ret) { | |
changedBrackets = true; | |
return ret; | |
} | |
} | |
return match; | |
}); | |
return { result, changedBrackets }; | |
} | |
function createElement(opts = {}) { | |
let { | |
tagName = 'div', | |
classes = [], | |
id = '', | |
text = '', | |
attrs = [], | |
style = null, | |
parent = null | |
} = opts; | |
let ele = document.createElement(tagName); | |
if(typeof classes === 'string' && classes.length) { | |
ele.classList.add(classes); | |
} | |
else if(Array.isArray(classes) && classes.length) { | |
ele.classList.add(...classes.filter(n => n)); | |
} | |
if(id) { | |
ele.id = id; | |
} | |
if(text) { | |
let hasBrackets = /\[.*?\]/g.test(text); | |
let { result = text, changedBrackets = false } = hasBrackets ? parseBrackets(text) : {}; | |
ele[changedBrackets ? 'innerHTML' : 'innerText'] = result; | |
} | |
if(Array.isArray(attrs)) { | |
if(attrs.length === 1) { | |
let [ attr ] = attrs; | |
ele.setAttribute(attr[0], attr[1]); | |
} | |
else if(attrs.length) { | |
attrs.forEach(attr => ele.setAttribute(attr[0], attr[1])); | |
} | |
} | |
else if(attrs) { | |
let keys = Object.keys(attrs); | |
keys.forEach(key => ele.setAttribute(key, attrs[key])); | |
} | |
if(style) { | |
let keys = Object.keys(style); | |
keys.forEach(key => ele.style[key] = style[key]); | |
} | |
if(parent) { | |
parent.appendChild(ele); | |
} | |
return ele; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url('https://fonts.googleapis.com/css?family=Open+Sans:300,400,500,700'); | |
body { | |
margin: 0; | |
font-family: 'Open Sans', Helvetica Neue, Helvetica, Arial, sans-serif; | |
font-size: 16px; | |
} | |
#header { | |
height: 86px; | |
background-color: hsl(0, 0%, 100%); | |
border-bottom: 12px solid hsl(208, 79%, 85%); | |
position: relative; | |
.logo, | |
.logo-network, | |
.logo-github { | |
background-size: contain; | |
background-position: center; | |
background-repeat: no-repeat; | |
position: absolute; | |
top: 50%; | |
} | |
.logo-network, | |
.logo-github { | |
width: 48px; | |
height: 48px; | |
cursor: pointer; | |
margin-top: -24px; | |
margin-left: -24px; | |
transition: transform 200ms; | |
&:hover { | |
transform: rotate(15deg); | |
} | |
} | |
.logo { | |
width: 62px; | |
height: 62px; | |
background-image: url(https://alca.tv/static/codepen/pens/zEXwQM/Logo.png); | |
left: 50%; | |
margin-top: -31px; | |
margin-left: -31px; | |
} | |
.logo-network { | |
background-image: url(https://alca.tv/static/codepen/pens/zEXwQM/CloudServerIcon.svg); | |
left: 25%; | |
} | |
.logo-github { | |
background-image: url(https://alca.tv/static/codepen/pens/zEXwQM/GitHub-Mark.svg); | |
left: 75%; | |
} | |
} | |
#demo { | |
background: linear-gradient(135deg, hsl(210, 93%, 77%) 0%, hsl(270, 94%, 88%) 100%); | |
padding: 28px 0 72px; | |
text-align: center; | |
.title { | |
font-size: 2.5em; | |
font-weight: 700; | |
color: hsl(0, 0%, 100%); | |
margin-bottom: 0.75em; | |
} | |
.invite-now-wrapper { | |
height: 102px; | |
.invite-now { | |
display: inline-block; | |
font-size: 2em; | |
font-weight: 700; | |
line-height: 1em; | |
color: hsl(208, 14%, 21%); | |
cursor: pointer; | |
padding: 0.5em 2em; | |
margin-bottom: 1em; | |
background-color: hsl(0, 0%, 100%); | |
border-radius: 40px; | |
border-bottom: 6px solid hsl(208, 79%, 85%); | |
transition: 200ms; | |
user-select: none; | |
&:hover { | |
border-bottom-width: 10px; | |
margin-top: -4px; | |
} | |
&:active { | |
border-bottom-width: 4px; | |
margin-top: 2px; | |
transition: 50ms; | |
} | |
} | |
} | |
.discord-app-mount { | |
text-align: left; | |
height: 600px; | |
position: relative; | |
} | |
} | |
.discord-app { | |
font-size: 16px; | |
user-select: none; | |
color: hsl(0, 0%, 100%); | |
width: 1000px; | |
height: 600px; | |
background: hsl(220, 8%, 23%); | |
position: absolute; | |
border-radius: 6px; | |
overflow: hidden; | |
left: 50%; | |
// top: 50%; | |
margin-left: -500px; | |
// margin-top: -250px; | |
::-webkit-scrollbar { | |
width: 14px; | |
} | |
::-webkit-scrollbar-thumb, | |
::-webkit-scrollbar-track-piece { | |
border-radius: 7px; | |
background-clip: padding-box; | |
border: 3px solid hsl(217, 7%, 23%); | |
} | |
::-webkit-scrollbar-thumb { | |
background-color: hsl(210, 9%, 13%); | |
} | |
::-webkit-scrollbar-track-piece { | |
background-color: hsl(223, 7%, 20%); | |
} | |
.app-buttons, | |
.app-buttons:before, | |
.app-buttons:after { | |
content: ''; | |
width: 10px; | |
height: 10px; | |
cursor: pointer; | |
border-radius: 50%; | |
position: absolute; | |
z-index: 4; | |
transition: 100ms; | |
} | |
.app-buttons { | |
background-color: hsl(44, 100%, 51%); | |
top: 8px; | |
left: 31px; | |
&:before { | |
background-color: hsl(5, 100%, 66%); | |
left: -18px; | |
} | |
&:after { | |
background-color: hsl(131, 81%, 44%); | |
left: 18px; | |
} | |
&:hover { | |
} | |
} | |
.emoji { | |
height: 1rem; | |
width: 1rem; | |
min-height: 22px; | |
min-width: 22px; | |
margin: 0 0.05em 0 0.1em !important; | |
vertical-align: -0.4em; | |
object-fit: contain; | |
} | |
} | |
.discord-app .guilds, | |
.discord-app .channels, | |
.discord-app .chat { | |
position: absolute; | |
top: 0; | |
bottom: 0; | |
} | |
.discord-app .guilds { | |
width: 70px; | |
padding: 36px 0 18px 10px; | |
box-sizing: border-box; | |
background: hsl(210, 9%, 13%); | |
overflow-y: auto; | |
left: 0; | |
.guild { | |
width: 50px; | |
height: 50px; | |
background: hsl(223, 7%, 20%); | |
border-radius: 50%; | |
cursor: pointer; | |
background-position: center; | |
background-repeat: no-repeat; | |
background-size: cover; | |
position: relative; | |
&.selected { | |
border-radius: 15px; | |
&:before { | |
content: ''; | |
display: block; | |
width: 10px; | |
height: 40px; | |
background: hsl(0, 0%, 100%); | |
border-radius: 20px; | |
position: absolute; | |
top: 50%; | |
left: -15px; | |
margin-top: -20px; | |
} | |
} | |
&.guild-add { | |
background: hsl(210, 9%, 10%); | |
border: 1px dashed hsl(220, 3%, 34%); | |
color: hsl(220, 3%, 34%); | |
font-size: 40px; | |
font-weight: 300; | |
line-height: 100%; | |
vertical-align: baseline; | |
text-align: center; | |
transition: border-color 250ms ease, | |
color 250ms ease; | |
&:after { | |
content: '+'; | |
position: relative; | |
top: 4px; | |
} | |
&:hover { | |
border-color: hsla(0,0%,100%,.75); | |
color: hsla(0,0%,100%,.75); | |
} | |
} | |
& + .guild { | |
margin-top: 8px; | |
} | |
} | |
} | |
.discord-app .channels .header, | |
.discord-app .chat .header { | |
height: 56px; | |
color: hsl(0, 0%, 100%); | |
line-height: 55px; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
box-sizing: border-box; | |
border-bottom: 1px solid hsla(0, 0%, 0%, 0.2); | |
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06); | |
} | |
.discord-app .channels, | |
.discord-app .chat textarea { | |
::-webkit-scrollbar { | |
width: 8px; | |
} | |
::-webkit-scrollbar-thumb, | |
::-webkit-scrollbar-track-piece { | |
border-color: hsla(0, 0%, 0%, 0); | |
border-radius: 4px; | |
border-style: solid; | |
border-width: 3px; | |
} | |
::-webkit-scrollbar-thumb { | |
background-color: hsl(216, 7%, 14%); | |
border: 2px solid hsla(0, 0%, 0%, 0); | |
} | |
::-webkit-scrollbar-track { | |
background-color: hsla(0, 0%, 0%, 0); | |
border: 2px solid hsla(0, 0%, 0%, 0); | |
visibility: hidden; | |
} | |
::-webkit-scrollbar-track-piece { | |
background-color: hsla(0, 0%, 0%, 0); | |
} | |
::-webkit-scrollbar-corner { | |
background-color: hsla(0, 0%, 0%, 0); | |
} | |
} | |
.discord-app .channels { | |
background-color: hsl(223, 7%, 20%); | |
width: 240px; | |
left: 70px; | |
.header { | |
font-weight: 500; | |
padding: 0 16px; | |
cursor: pointer; | |
transition: background-color 150ms ease; | |
z-index: 3; | |
&:hover { | |
background-color: hsla(0, 0%, 0%, 0.2); | |
} | |
} | |
.channel-wrapper { | |
padding-top: 16px; | |
overflow-y: auto; | |
position: absolute; | |
top: 56px; | |
bottom: 52px; | |
left: 0; | |
right: 0; | |
.channel { | |
width: 224px; | |
height: 32px; | |
line-height: 32px; | |
padding: 0 8px; | |
margin: 1px 0 1px 8px; | |
border-radius: 3px; | |
box-sizing: border-box; | |
transition: 50ms; | |
&.selected { | |
background-color: hsla(217, 8%, 34%, 0.6); | |
} | |
&:not(.selected) { | |
cursor: pointer; | |
&:hover { | |
background-color: hsl(220, 8%, 23%); | |
} | |
} | |
&:before { | |
content: '#'; | |
font-size: 20px; | |
font-weight: 400; | |
color: hsla(216, 4%, 74%, 0.6); | |
margin-right: 4px; | |
vertical-align: top; | |
} | |
} | |
} | |
.user { | |
height: 52px; | |
background-color: hsla(216, 7%, 14%, 0.3); | |
position: absolute; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
} | |
} | |
.discord-app .chat { | |
background-color: hsl(217, 7%, 23%); | |
left: 310px; | |
right: 0; | |
.header { | |
padding: 0 5px 0 20px; | |
font-weight: 700; | |
font-size: 20px; | |
line-height: 52px; | |
&:before { | |
content: '#'; | |
margin-right: 4px; | |
color: hsl(216, 4%, 56%); | |
font-size: 24px; | |
font-weight: 400; | |
vertical-align: top; | |
} | |
} | |
.messages-wrapper { | |
overflow-x: hidden; | |
overflow-y: auto; | |
position: absolute; | |
top: 56px; | |
left: 0; | |
right: 0; | |
bottom: 95px; | |
} | |
.messages { | |
left: 0; | |
right: 0; | |
bottom: 0; | |
&.attached { | |
position: absolute; | |
bottom: 0; | |
} | |
&.hide { | |
transform: translate3D(50px, 0, 0); | |
opacity: 0; | |
transition: 300ms ease-in; | |
} | |
} | |
.message-group { | |
margin: 0 6px 0 20px; | |
padding: 0; | |
overflow: hidden; | |
opacity: 0; | |
max-height: 0; | |
transform: perspective(600px) translate3D(0, 0, -50px); | |
transition: 1000ms max-height, 100ms padding, 200ms opacity, 400ms transform; | |
& + .message-group { | |
border-top: 1px solid hsla(0, 0%, 100%, 0.04); | |
} | |
&.animate-in { | |
padding: 20px 0; | |
opacity: 1; | |
max-height: 1000px; | |
transform: perspective(600px) translate3D(0, 0, 0); | |
} | |
.avatar, | |
.comment { | |
vertical-align: top; | |
display: inline-block; | |
} | |
.avatar { | |
width: 40px; | |
height: 40px; | |
background-color: hsla(0, 0%, 100%, 0.1); | |
background-size: cover; | |
border-radius: 50%; | |
margin: -2px 20px 0 0; | |
} | |
.comment { | |
width: 550px; | |
} | |
.username-wrapper { | |
font-size: 0; | |
.username, | |
.bot-tag, | |
.timestamp { | |
display: inline-block; | |
vertical-align: baseline; | |
font-size: 1rem; | |
} | |
.username { | |
font-weight: 500; | |
cursor: pointer; | |
&:hover { | |
text-decoration: underline; | |
} | |
} | |
.bot-tag { | |
background-color: hsl(227, 58%, 65%); | |
color: hsl(0, 0%, 100%); | |
border-radius: 3px; | |
font-size: 10px; | |
font-weight: 500; | |
line-height: 16px; | |
margin-left: 6px; | |
padding: 1px 2px; | |
text-transform: uppercase; | |
vertical-align: bottom; | |
&:before { | |
content: 'BOT'; | |
} | |
} | |
.timestamp { | |
font-size: 0.75rem; | |
color: hsla(0, 0%, 100%, 0.2); | |
margin-left: 6px; | |
} | |
} | |
} | |
.message { | |
opacity: 0; | |
transform: perspective(600px) translate3D(0, 0, -50px); | |
transition: opacity 800ms, 250ms transform; | |
&.animate-in { | |
opacity: 1; | |
transform: perspective(600px) translate3D(0, 0, 0); | |
} | |
.body { | |
// & + .embed { | |
// margin-top: | |
// } | |
} | |
.message-text { | |
color: hsla(0, 0%, 100%, 0.7); | |
// color: hsl(212, 10%, 50%); | |
font-size: 0.9375rem; | |
line-height: 1.1em; | |
margin-top: 6px; | |
white-space: pre-wrap; | |
word-wrap: break-word; | |
} | |
.embed { | |
display: flex; | |
max-width: 520px; | |
margin-top: 5px; | |
position: relative; | |
.embed-pill { | |
width: 4px; | |
border-radius: 3px 0 0 3px; | |
background-color: #4f545c; | |
flex-shrink: 0; | |
} | |
.embed-rich { | |
display: flex; | |
box-sizing: border-box; | |
flex-direction: column; | |
background-color: rgba(46,48,54,.3); | |
border-color: rgba(46,48,54,.6); | |
border-radius: 0 3px 3px 0; | |
padding: 8px 10px; | |
position: relative; | |
.embed-footer-icon, | |
.embed-footer { | |
vertical-align: baseline; | |
} | |
.embed-footer-icon { | |
border-radius: 2.45px; | |
float: left; | |
height: 18px; | |
margin-right: 10px; | |
object-fit: contain; | |
width: 18px; | |
} | |
.embed-footer { | |
color: hsla(0, 0%, 100%, 0.6); | |
display: inline-block; | |
font-size: 0.75rem; | |
font-weight: 500; | |
letter-spacing: 0; | |
transform: translate3d(0, -3px, 0); | |
} | |
} | |
} | |
} | |
.input-wrapper { | |
// height: 95px; | |
padding: 20px 0 30px; | |
box-sizing: border-box; | |
border-top: 1px solid hsla(0, 0%, 100%, 0.06); | |
position: absolute; | |
left: 20px; | |
right: 20px; | |
bottom: 0; | |
.input { | |
height: 44px; | |
background-color: hsla(218, 5%, 47%, 0.3); | |
border-radius: 5px; | |
textarea { | |
font-family: inherit; | |
height: auto; | |
background-color: hsla(0, 0%, 0%, 0); | |
color: hsla(0, 0%, 100%, 0.7); | |
padding: 10px 38px 10px 12px; | |
appearance: none; | |
border: none; | |
font-size: 0.9375rem; | |
font-weight: 400; | |
letter-spacing: -0.025rem; | |
line-height: 1.25rem; | |
margin: 2px 2px 2px 0; | |
max-height: 144px; | |
min-height: 20px; | |
outline: none; | |
resize: none; | |
width: 100%; | |
} | |
} | |
} | |
} | |
.discord-app .chat .message .embed .embed-content { | |
display: flex; | |
margin-bottom: 10px; | |
width: 100%; | |
.embed-inner-content { | |
flex: 1; | |
.embed-title { | |
color: hsl(0, 0%, 100%); | |
font-size: 0.875rem; | |
} | |
.embed-fields { | |
display: flex; | |
flex-direction: row; | |
flex-wrap: wrap; | |
margin-top: -10px; | |
color: hsla(0, 0%, 100%, 0.6); | |
.embed-field { | |
flex: 0; | |
max-width: 506px; | |
min-width: 100%; | |
padding-top: 10px; | |
&.embed-field-inline { | |
flex: 1; | |
flex-basis: auto; | |
min-width: 150px; | |
} | |
.embed-field-name { | |
color: hsl(0, 0%, 100%); | |
font-size: 0.825rem; | |
font-weight: 500; | |
margin-bottom: 4px; | |
} | |
.embed-field-value { | |
color: hsla(0, 0%, 100%, 0.7); | |
font-size: 0.775rem; | |
font-weight: 400; | |
line-height: 0.9625rem; | |
white-space: pre-line; | |
} | |
} | |
} | |
} | |
.embed-thumb { | |
border-radius: 3px; | |
flex-shrink: 0; | |
margin-left: 20px; | |
max-height: 80px; | |
max-width: 80px; | |
object-fit: contain; | |
width: auto; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment