mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Add orbis floating chat
This commit is contained in:
parent
e639b419d8
commit
07d69c1fb6
3
src/@images/send.svg
Normal file
3
src/@images/send.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.17699 1.119C1.25168 1.05563 1.34333 1.01559 1.44058 1.00386C1.53782 0.992127 1.63637 1.00921 1.72399 1.053L14.724 7.553C14.8069 7.59457 14.8767 7.6584 14.9254 7.73734C14.9741 7.81628 15 7.90723 15 8C15 8.09278 14.9741 8.18372 14.9254 8.26266C14.8767 8.34161 14.8069 8.40543 14.724 8.447L1.72399 14.947C1.63643 14.9909 1.5379 15.0081 1.44065 14.9965C1.34339 14.9849 1.25168 14.945 1.17691 14.8817C1.10213 14.8185 1.04759 14.7346 1.02005 14.6406C0.992509 14.5466 0.993183 14.4466 1.02199 14.353L2.97699 8L1.02199 1.647C0.993347 1.55348 0.992767 1.45361 1.02032 1.35976C1.04787 1.26591 1.10234 1.1822 1.17699 1.119V1.119ZM3.86899 8.5L2.32199 13.53L13.382 8L2.32199 2.47L3.86899 7.5H9.49999C9.63259 7.5 9.75977 7.55268 9.85354 7.64645C9.94731 7.74022 9.99999 7.86739 9.99999 8C9.99999 8.13261 9.94731 8.25979 9.85354 8.35355C9.75977 8.44732 9.63259 8.5 9.49999 8.5H3.86999H3.86899Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 996 B |
@ -0,0 +1,46 @@
|
||||
.chatToolbar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
background-color: var(--background-content);
|
||||
padding: calc(var(--spacer) / 2);
|
||||
border-top: 1px solid var(--border-color);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.chatMessage {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: calc(var(--spacer) / 2);
|
||||
}
|
||||
|
||||
.chatMessage div {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.chatMessage label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.button {
|
||||
right: calc(var(--spacer) / 4);
|
||||
background-color: var(--background-content);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: var(--brand-white);
|
||||
font-size: var(--font-size-title);
|
||||
transition: color 200ms ease;
|
||||
}
|
||||
|
||||
.button:hover,
|
||||
.button:focus {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.sendIcon {
|
||||
fill: currentColor;
|
||||
}
|
22
src/components/@shared/Orbis/FloatingChat/ChatToolbar.tsx
Normal file
22
src/components/@shared/Orbis/FloatingChat/ChatToolbar.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react'
|
||||
import styles from './ChatToolbar.module.css'
|
||||
import SendIcon from '@images/send.svg'
|
||||
import Input from '@shared/FormInput'
|
||||
|
||||
export default function ChatToolbar() {
|
||||
return (
|
||||
<div className={styles.chatToolbar}>
|
||||
<form className={styles.chatMessage}>
|
||||
<Input
|
||||
type="input"
|
||||
name="message"
|
||||
size="small"
|
||||
placeholder="Type Message"
|
||||
/>
|
||||
<button className={styles.button}>
|
||||
<SendIcon className={styles.sendIcon} />
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
.conversationBox {
|
||||
padding: calc(var(--spacer) / 2);
|
||||
height: calc(100% - (var(--spacer) * 3.5));
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.conversationRecipient,
|
||||
.conversationSend {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
margin-bottom: calc(var(--spacer) / 2);
|
||||
}
|
||||
|
||||
.conversationSend .chatBubbleItem {
|
||||
text-align: right;
|
||||
padding-left: 48px;
|
||||
}
|
||||
|
||||
.colAvatar {
|
||||
flex-shrink: 0;
|
||||
padding-right: calc(var(--spacer) / 2);
|
||||
}
|
||||
|
||||
.avatar {
|
||||
aspect-ratio: 1/1;
|
||||
border-radius: 100%;
|
||||
border: 1px solid var(--border-color);
|
||||
flex-shrink: 0;
|
||||
width: calc(var(--font-size-large) * 2);
|
||||
height: calc(var(--font-size-large) * 2);
|
||||
}
|
||||
|
||||
.colBubble {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chatBubbleItem {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.chatBubbleItem + .chatBubbleItem {
|
||||
margin-top: calc(var(--spacer) / 8);
|
||||
}
|
||||
|
||||
.chatBubble {
|
||||
display: inline-block;
|
||||
background-color: var(--color-primary);
|
||||
padding: calc(var(--spacer) / 4) calc(var(--spacer) / 2.5);
|
||||
font-size: var(--font-size-base);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.chatPrimary {
|
||||
color: var(--brand-white);
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.chatDefault {
|
||||
background-color: var(--border-color);
|
||||
}
|
||||
|
||||
.conversationRecipient .colBubble .chatBubbleItem .chatBubble {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
.conversationRecipient .colBubble .chatBubbleItem:first-of-type .chatBubble {
|
||||
border-top-left-radius: 1rem;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
.conversationSend .colBubble .chatBubbleItem .chatBubble {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.conversationSend .colBubble .chatBubbleItem:first-of-type .chatBubble {
|
||||
border-top-right-radius: 1rem;
|
||||
border-bottom-left-radius: 0px;
|
||||
}
|
||||
|
||||
.chatStamp {
|
||||
font-size: var(--font-size-small);
|
||||
color: var(--color-secondary);
|
||||
padding-top: calc(var(--spacer) / 8);
|
||||
}
|
89
src/components/@shared/Orbis/FloatingChat/Conversation.tsx
Normal file
89
src/components/@shared/Orbis/FloatingChat/Conversation.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
import React from 'react'
|
||||
import styles from './Conversation.module.css'
|
||||
|
||||
export default function DmConversation() {
|
||||
const dummyData = [
|
||||
{
|
||||
name: 'realdatawhale.eth',
|
||||
image: '/apple-touch-icon.png',
|
||||
chat1: 'Hello friend whats up!',
|
||||
chat2:
|
||||
'I have this exact same issue with using brave browser. It wont prompt for metamask instead asking to connect to brave wallet.',
|
||||
chat3: 'Hello!',
|
||||
chat4: 'Yeah thats weird!',
|
||||
chat5:
|
||||
'Did you update your profile within Orbis or with an app you built?!',
|
||||
timestamp: 'Jul 27, 2022, 3:39 AM'
|
||||
}
|
||||
]
|
||||
|
||||
return (
|
||||
<>
|
||||
{dummyData.map((dm, index) => (
|
||||
<div className={styles.conversationBox} key={index}>
|
||||
<div className={styles.conversationRecipient}>
|
||||
<div className={styles.colAvatar}>
|
||||
<img src={dm.image} alt="Avatar" className={styles.avatar}></img>
|
||||
</div>
|
||||
<div className={styles.colBubble}>
|
||||
<div className={styles.chatBubbleItem}>
|
||||
<div className={`${styles.chatBubble} ${styles.chatPrimary}`}>
|
||||
{dm.chat1}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.chatBubbleItem}>
|
||||
<div className={`${styles.chatBubble} ${styles.chatPrimary}`}>
|
||||
{dm.chat2}
|
||||
</div>
|
||||
<div className={styles.chatStamp}>{dm.timestamp}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.conversationSend}>
|
||||
<div className={styles.colBubble}>
|
||||
<div className={styles.chatBubbleItem}>
|
||||
<div className={`${styles.chatBubble} ${styles.chatDefault}`}>
|
||||
{dm.chat3}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.chatBubbleItem}>
|
||||
<div className={`${styles.chatBubble} ${styles.chatDefault}`}>
|
||||
{dm.chat4}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.chatBubbleItem}>
|
||||
<div className={`${styles.chatBubble} ${styles.chatDefault}`}>
|
||||
{dm.chat5}
|
||||
</div>
|
||||
<div className={styles.chatStamp}>{dm.timestamp}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.conversationRecipient}>
|
||||
<div className={styles.colAvatar}>
|
||||
<img src={dm.image} alt="Avatar" className={styles.avatar}></img>
|
||||
</div>
|
||||
<div className={styles.colBubble}>
|
||||
<div className={styles.chatBubbleItem}>
|
||||
<div className={`${styles.chatBubble} ${styles.chatPrimary}`}>
|
||||
{dm.chat1}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.chatBubbleItem}>
|
||||
<div className={`${styles.chatBubble} ${styles.chatPrimary}`}>
|
||||
{dm.chat4}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.chatBubbleItem}>
|
||||
<div className={`${styles.chatBubble} ${styles.chatPrimary}`}>
|
||||
{dm.chat2}
|
||||
</div>
|
||||
<div className={styles.chatStamp}>{dm.timestamp}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function DmDetails() {
|
||||
return <div>DmDetails</div>
|
||||
}
|
@ -9,23 +9,24 @@
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
transition: all 300ms ease 0s;
|
||||
transition: transform 300ms ease 0s;
|
||||
pointer-events: none;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.floating {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
pointer-events: auto;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
height: 530px;
|
||||
max-height: 80vh;
|
||||
background-color: var(--brand-black);
|
||||
background-color: var(--background-content);
|
||||
border: 1px solid var(--border-color);
|
||||
border-bottom: 0;
|
||||
border-radius: var(--border-radius);
|
||||
transform: translateY(0);
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.isClosed {
|
||||
@ -36,6 +37,7 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: calc(0.35 * var(--spacer)) var(--spacer);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
box-shadow: var(--box-shadow);
|
||||
@ -50,6 +52,22 @@
|
||||
fill: var(--font-color-text);
|
||||
}
|
||||
|
||||
.back {
|
||||
margin-left: 0;
|
||||
width: 1rem;
|
||||
margin-right: calc(0.5 * var(--spacer));
|
||||
fill: var(--font-color-text);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.btnBack {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
cursor: pointer;
|
||||
margin-left: auto;
|
||||
@ -68,9 +86,92 @@
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
.dmList {
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dmItem {
|
||||
padding: calc(var(--spacer) / 2);
|
||||
display: flex;
|
||||
padding: calc(var(--spacer) / 2) var(--spacer);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dmDate {
|
||||
font-size: var(--font-size-mini);
|
||||
color: var(--font-color-text);
|
||||
min-width: calc(var(--spacer) * 1.5);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.dmCount {
|
||||
background-color: var(--color-primary);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
color: var(--brand-white);
|
||||
border-radius: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: var(--font-size-mini);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.accountAvatarSet .dmCount {
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
right: -4px;
|
||||
}
|
||||
|
||||
.header .dmCount {
|
||||
margin-left: calc(var(--spacer) / 4);
|
||||
}
|
||||
|
||||
.accountInfo {
|
||||
-webkit-box-flex: 1;
|
||||
flex: 1;
|
||||
padding-left: calc(var(--spacer) / 2);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.accountHeading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.accountAvatarSet {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.accountAvatar {
|
||||
aspect-ratio: 1/1;
|
||||
border-radius: 100%;
|
||||
border: 1px solid var(--border-color);
|
||||
flex-shrink: 0;
|
||||
width: calc(var(--font-size-large) * 2.5);
|
||||
height: calc(var(--font-size-large) * 2.5);
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.accountName {
|
||||
margin-bottom: calc(var(--spacer) / 6);
|
||||
font-size: var(--font-size-medium);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.accountChat {
|
||||
font-size: var(--font-size-small);
|
||||
color: var(--color-secondary);
|
||||
margin-bottom: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dmDetails {
|
||||
@ -79,7 +180,8 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--background-body);
|
||||
height: 100%;
|
||||
background-color: var(--background-content);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 42rem) {
|
||||
|
@ -1,16 +1,52 @@
|
||||
import React, { useState } from 'react'
|
||||
import ChatBubble from '@images/chatbubble.svg'
|
||||
import ArrowBack from '@images/arrow.svg'
|
||||
import ChevronDoubleUp from '@images/chevrondoubleup.svg'
|
||||
import styles from './index.module.css'
|
||||
import Conversation from './Conversation'
|
||||
import ChatToolbar from './ChatToolbar'
|
||||
|
||||
export default function FloatingChat() {
|
||||
const [opened, setOpened] = useState(false)
|
||||
const [dmDetails, setDmDetails] = useState(null)
|
||||
|
||||
const dummyData = [{ name: 'John' }, { name: 'Jane' }]
|
||||
const dummyData = [
|
||||
{
|
||||
name: '0xd30D…AFbD',
|
||||
chat: 'Hello world!',
|
||||
date: '15 Minutes Ago',
|
||||
image: '/apple-touch-icon.png',
|
||||
count: '3'
|
||||
},
|
||||
{
|
||||
name: 'realdatawhale.eth',
|
||||
chat: 'Getting some similar glitches with profile NFT. The current non-NFT photo works fine.',
|
||||
date: '1 Day Ago',
|
||||
image: '/apple-touch-icon.png',
|
||||
count: '1'
|
||||
},
|
||||
{
|
||||
name: 'hidetaka.eth',
|
||||
chat: 'I already updated in the past.',
|
||||
date: '1 Oct',
|
||||
image: '/apple-touch-icon.png',
|
||||
count: '0'
|
||||
},
|
||||
{
|
||||
name: 'orbisclub.eth',
|
||||
chat: 'Yeah that is weird, Did you update your profile within Orbis or with an app you built',
|
||||
date: '1 Oct',
|
||||
image: '/apple-touch-icon.png',
|
||||
count: '0'
|
||||
}
|
||||
]
|
||||
|
||||
const openDetails = (name: string) => {
|
||||
setDmDetails(name)
|
||||
const sumCount = dummyData.reduce(function (prev, current) {
|
||||
return prev + +current.count
|
||||
}, 0)
|
||||
|
||||
function openDetails(id: string) {
|
||||
setDmDetails(id)
|
||||
}
|
||||
|
||||
return (
|
||||
@ -19,6 +55,7 @@ export default function FloatingChat() {
|
||||
<div className={styles.header}>
|
||||
<ChatBubble role="img" aria-label="Chat" className={styles.icon} />
|
||||
<span>Direct Messages</span>
|
||||
{sumCount > 0 && <span className={styles.dmCount}>{sumCount}</span>}
|
||||
<button
|
||||
type="button"
|
||||
className={styles.toggle}
|
||||
@ -31,21 +68,65 @@ export default function FloatingChat() {
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div className={styles.dmList}>
|
||||
{dummyData.map((dm, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={styles.dmItem}
|
||||
onClick={() => openDetails(dm.name)}
|
||||
>
|
||||
{dm.name}
|
||||
<div className={styles.accountAvatarSet}>
|
||||
<img
|
||||
src={dm.image}
|
||||
alt="Avatar"
|
||||
className={styles.accountAvatar}
|
||||
></img>
|
||||
{dm.count > '0' && (
|
||||
<div className={styles.dmCount}>{dm.count}</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.accountInfo}>
|
||||
<div className={styles.accountHeading}>
|
||||
<h3 className={styles.accountName}>{dm.name}</h3>
|
||||
<span className={styles.dmDate}>{dm.date}</span>
|
||||
</div>
|
||||
<p className={styles.accountChat}>{dm.chat}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{dmDetails && (
|
||||
<div className={styles.dmDetails}>Details {dmDetails}</div>
|
||||
)}
|
||||
</div>
|
||||
{dmDetails && (
|
||||
<div className={styles.dmDetails}>
|
||||
<div className={styles.header}>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="button"
|
||||
className={styles.btnBack}
|
||||
onClick={() => openDetails(null)}
|
||||
>
|
||||
<ArrowBack
|
||||
role="img"
|
||||
aria-label="arrow"
|
||||
className={styles.back}
|
||||
/>
|
||||
</button>
|
||||
<span>{dmDetails}</span>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.toggle}
|
||||
onClick={() => setOpened(!opened)}
|
||||
>
|
||||
<ChevronDoubleUp
|
||||
role="img"
|
||||
aria-label="Toggle"
|
||||
className={`${styles.icon} ${opened && styles.isFlipped}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<Conversation />
|
||||
<ChatToolbar />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user