mirror of
https://framagit.org/tykayn/mastodon.git
synced 2023-08-25 08:33:12 +02:00
⚡ split of css
Signed-off-by: Baptiste Lemoine <contact@cipherbliss.com>
This commit is contained in:
parent
80751c0ca1
commit
9bef612c35
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import accounts, { me } from '../../../../initial_state';
|
||||
import api from '../../../../api';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { mockContactList } from './mockContactList';
|
||||
import { mockContactList } from './mocks/mockContactList';
|
||||
import Contact from './Contact';
|
||||
|
||||
export default class ContactsList extends ImmutablePureComponent {
|
||||
@ -84,10 +84,10 @@ export default class ContactsList extends ImmutablePureComponent {
|
||||
return (
|
||||
<div className='messaging-container'>
|
||||
<div className={classListContainer}>
|
||||
<div className='title column-header'>
|
||||
<div className='card-title '>
|
||||
<i
|
||||
role='img'
|
||||
className='fa fa-envelope column-header__icon fa-fw'
|
||||
className='fa fa-comment column-header__icon fa-fw'
|
||||
/>
|
||||
{this.state.following_count} contacts
|
||||
<button
|
||||
|
@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import Contact from './Contact';
|
||||
import PropTypes from 'prop-types';
|
||||
import ConversationStream from './conversation-stream';
|
||||
|
||||
@ -23,38 +22,57 @@ export default class ConversationItem extends React.PureComponent {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
console.log('props', props);
|
||||
this.state = {
|
||||
composeMessage: '',
|
||||
displayed : this.props.displayed,
|
||||
newMessages : this.props.newMessages,
|
||||
isFocused : false,
|
||||
};
|
||||
}
|
||||
|
||||
submitCompose() {
|
||||
console.log('submit');
|
||||
}
|
||||
submitCompose = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
handleChange(e) {
|
||||
// e.preventDefault();
|
||||
console.log('submit');
|
||||
};
|
||||
|
||||
toggleVisibility = () => {
|
||||
this.setState({ 'displayed': !this.state.displayed });
|
||||
};
|
||||
toggleFocused = () => {
|
||||
this.setState({ 'isFocused': !this.state.isFocused });
|
||||
};
|
||||
|
||||
handleChange = (e) => {
|
||||
e.preventDefault();
|
||||
console.log('e', e);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const hasNewClass = this.props.newMessages ? 'has-new-message' : 'nothing-new';
|
||||
const isVisible = this.props.displayed ? 'displayed' : 'hidden';
|
||||
const hasNewClass = this.state.newMessages ? 'has-new-message' : 'nothing-new';
|
||||
const isVisible = this.state.displayed ? 'displayed' : 'hidden';
|
||||
const isFocused = this.state.isFocused ? 'isFocused' : 'not-focused';
|
||||
const list = (
|
||||
<li className={'conversation-item ' + hasNewClass + ' ' + isVisible}>
|
||||
<li className={'conversation-item ' + hasNewClass + ' ' + isVisible + ' ' + isFocused}>
|
||||
<div className='top-title'>
|
||||
<i
|
||||
role='img'
|
||||
className='fa fa-envelope column-header__icon fa-fw'
|
||||
className='fa fa-comment-o column-header__icon fa-fw'
|
||||
/>
|
||||
<Contact account={this.props.recipient} />
|
||||
{this.props.newMessages && (
|
||||
<span className='username'>
|
||||
{this.props.recipient.username}
|
||||
</span >
|
||||
{/*<Contact account={this.props.recipient} />*/}
|
||||
{this.props.newMessages > 0 && (
|
||||
<span className='new-message-counter'>
|
||||
({this.props.newMessages})
|
||||
</span >
|
||||
)}
|
||||
<button className='btn-small'>
|
||||
<button
|
||||
className='btn btn-small'
|
||||
onClick={this.toggleVisibility}
|
||||
>
|
||||
<i
|
||||
role='img'
|
||||
className='fa fa-caret-down column-header__icon fa-fw'
|
||||
@ -74,7 +92,8 @@ export default class ConversationItem extends React.PureComponent {
|
||||
rows='3'
|
||||
className='messager-textarea'
|
||||
placeholder='allez dis nous tout'
|
||||
value={this.state.composeMessage}
|
||||
onFocusCapture={this.toggleFocused}
|
||||
onBlurCapture={this.toggleFocused}
|
||||
onChange={this.handleChange}
|
||||
|
||||
/>
|
||||
@ -87,7 +106,11 @@ export default class ConversationItem extends React.PureComponent {
|
||||
</div >
|
||||
</li >
|
||||
);
|
||||
return list;
|
||||
return (
|
||||
<ul >
|
||||
{list}
|
||||
</ul >
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default class ConversationStream extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
messages: PropTypes.array,
|
||||
};
|
||||
@ -17,7 +18,7 @@ export default class ConversationStream extends React.PureComponent {
|
||||
|
||||
messagesLists = this.props.messages.map(message => {
|
||||
return (
|
||||
<li className={'message ' + message.text}>
|
||||
<li className={'message ' + message.who}>
|
||||
<p >{message.text}</p >
|
||||
<div className='arrow-down' />
|
||||
</li >
|
||||
@ -27,9 +28,9 @@ export default class ConversationStream extends React.PureComponent {
|
||||
}
|
||||
return (
|
||||
<div className='conversation-stream'>
|
||||
<ul className='messages'>
|
||||
<div className='messages'>
|
||||
{messagesLists}
|
||||
</ul >
|
||||
</div >
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import ConversationItem from './conversation-item';
|
||||
import { mockRecipient, mockRecipient2 } from './mockConversation';
|
||||
import { mockRecipient, mockRecipient2 } from './mocks/mockConversation';
|
||||
|
||||
export default class ConversationStack extends React.Component {
|
||||
|
||||
@ -19,21 +19,27 @@ export default class ConversationStack extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let list = this.props.conversations.map(conversations =>
|
||||
(
|
||||
<li
|
||||
className='conversation-item-wrapper'
|
||||
key={conversations.id}
|
||||
>
|
||||
<ConversationItem
|
||||
recipient={mockRecipient}
|
||||
messages={mockRecipient.messages}
|
||||
key={conversations.id}
|
||||
onClick={this.openConversationWith}
|
||||
/>
|
||||
</li >
|
||||
),
|
||||
);
|
||||
let list = this.props.conversations.map(recipient => {
|
||||
|
||||
console.log('recipient', recipient);
|
||||
recipient = recipient[0];
|
||||
return (
|
||||
<li
|
||||
className='conversation-item-wrapper'
|
||||
key={'wrapper' + recipient.id}
|
||||
>
|
||||
<ConversationItem
|
||||
recipient={recipient}
|
||||
messages={recipient.messages}
|
||||
key={'ConversationItem_' + recipient.id}
|
||||
onClick={this.openConversationWith}
|
||||
/>
|
||||
</li >
|
||||
);
|
||||
|
||||
},
|
||||
)
|
||||
;
|
||||
return (
|
||||
<ul className='stack conversations_list'>
|
||||
{list}
|
||||
|
@ -2,6 +2,9 @@ import React from 'react';
|
||||
import ContactsList from './contacts-list';
|
||||
import ConversationStack from './conversationStack';
|
||||
|
||||
/**
|
||||
* main component for IM, gathers contact list and list of conversations
|
||||
*/
|
||||
export default class InstantMessaging extends React.PureComponent {
|
||||
|
||||
// static propTypes = {
|
||||
@ -28,7 +31,7 @@ export default class InstantMessaging extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div >
|
||||
<div className='main-instant-messaging'>
|
||||
|
||||
<ContactsList />
|
||||
<ConversationStack />
|
||||
|
@ -25,7 +25,7 @@ export const mockRecipient = [
|
||||
export const mockRecipient2 = [
|
||||
{
|
||||
id : 4,
|
||||
username : 'the Bo botte',
|
||||
username : 'the Bo Botte',
|
||||
newMessages: 0,
|
||||
messages : mockMessages2,
|
||||
},
|
@ -1,177 +1 @@
|
||||
$messagingBoxWidth: 20em;
|
||||
$messagingBoxHeight: 100%;
|
||||
$conversationBoxHeight: 20em;
|
||||
|
||||
.fixed-box {
|
||||
border: solid 1px white;
|
||||
padding: 1em;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.airmail-border {
|
||||
border: 0.25em solid transparent;
|
||||
border-image: 4 repeating-linear-gradient(-45deg, red 0, red 1em, white 0, white 2em,
|
||||
#58a 0, #58a 3em, white 0, white 4em);
|
||||
|
||||
}
|
||||
|
||||
.status-direct,
|
||||
.item-list .conversation {
|
||||
@extend .airmail-border;
|
||||
}
|
||||
|
||||
.messaging-box {
|
||||
@extend .fixed-box;
|
||||
|
||||
right: 1em;
|
||||
width: $messagingBoxWidth;
|
||||
background: $ui-base-color;
|
||||
height: 4em;
|
||||
color: white;
|
||||
z-index: 10;
|
||||
|
||||
&.active {
|
||||
height: $messagingBoxHeight;
|
||||
}
|
||||
|
||||
.messager-textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.contact-list-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.contact-list {
|
||||
display: block;
|
||||
padding: 1em;
|
||||
min-height: 5em;
|
||||
list-style-type: none;
|
||||
color: white;
|
||||
|
||||
.contact {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.toggle-list {
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
background: $ui-primary-color;
|
||||
border: 0;
|
||||
padding: .5em;
|
||||
|
||||
&.active {
|
||||
background: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.conversation {
|
||||
|
||||
|
||||
.conversation__content {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.conversation_reply,
|
||||
.icon-button {
|
||||
&:hover {
|
||||
color: $ui-highlight-color;
|
||||
background: mix($ui-base-color, $ui-secondary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.conversation_reply,
|
||||
.icon-button,
|
||||
.status__action-bar-dropdown {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
width: 18em;
|
||||
height: 3.2em;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.conversations_list {
|
||||
@extend .fixed-box;
|
||||
right: $messagingBoxWidth + 2em;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 0.5em;
|
||||
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.conversation-item {
|
||||
float: right;
|
||||
width: 20em;
|
||||
margin-left: 2em;
|
||||
padding: 1em;
|
||||
border-radius: 15px;
|
||||
background: $classic-base-color;
|
||||
|
||||
&.has-new-message {
|
||||
background: $ui-highlight-color;
|
||||
color: $classic-primary-color;
|
||||
}
|
||||
}
|
||||
|
||||
.conversation_created-at {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.conversation_stream {
|
||||
padding-top: 1em;
|
||||
height: $conversationBoxHeight;
|
||||
overflow: auto;
|
||||
background: $ui-secondary-color;
|
||||
|
||||
.message {
|
||||
-webkit-border-radius: 0.5rem;
|
||||
-moz-border-radius: 0.5rem;
|
||||
border-radius: 0.5rem;
|
||||
margin-bottom: 0.5em;
|
||||
padding: 0.5em 1em;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.mine {
|
||||
text-align: right;
|
||||
background: $classic-primary-color;
|
||||
float: right;
|
||||
|
||||
.arrow-down {
|
||||
border-top-color: $classic-primary-color;
|
||||
left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.theirs {
|
||||
text-align: left;
|
||||
background: $ui-highlight-color;
|
||||
float: left;
|
||||
|
||||
.arrow-down {
|
||||
border-top-color: $ui-highlight-color;
|
||||
right: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.arrow-down {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 20px solid transparent;
|
||||
border-top: 20px solid $classic-primary-color;
|
||||
position: relative;
|
||||
bottom: -1em;
|
||||
|
||||
}
|
||||
}
|
||||
@import "../mastodon/messaging/main";
|
||||
|
3
app/javascript/styles/mastodon/messaging/config.scss
Normal file
3
app/javascript/styles/mastodon/messaging/config.scss
Normal file
@ -0,0 +1,3 @@
|
||||
$messagingBoxWidth: 20em;
|
||||
$messagingBoxHeight: 100%;
|
||||
$conversationBoxHeight: 20em;
|
16
app/javascript/styles/mastodon/messaging/contacts.scss
Normal file
16
app/javascript/styles/mastodon/messaging/contacts.scss
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
.contact-list-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.contact-list {
|
||||
display: block;
|
||||
padding: 1em;
|
||||
min-height: 5em;
|
||||
list-style-type: none;
|
||||
color: white;
|
||||
|
||||
.contact {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
16
app/javascript/styles/mastodon/messaging/helpers.scss
Normal file
16
app/javascript/styles/mastodon/messaging/helpers.scss
Normal file
@ -0,0 +1,16 @@
|
||||
.fixed-box {
|
||||
border: solid 1px white;
|
||||
padding: 1em;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.airmail-border {
|
||||
border: 0.25em solid transparent;
|
||||
border-image: 4 repeating-linear-gradient(-45deg, red 0, red 1em, white 0, white 2em,
|
||||
#58a 0, #58a 3em, white 0, white 4em);
|
||||
border-right-width: 0;
|
||||
border-bottom-width: 0;
|
||||
border-top-width: 0;
|
||||
|
||||
}
|
6
app/javascript/styles/mastodon/messaging/main.scss
Normal file
6
app/javascript/styles/mastodon/messaging/main.scss
Normal file
@ -0,0 +1,6 @@
|
||||
@import "config";
|
||||
@import "helpers";
|
||||
@import "messaging";
|
||||
@import "contacts";
|
||||
@import "messaging-conversation";
|
||||
@import "messaging-stream";
|
@ -0,0 +1,84 @@
|
||||
|
||||
.conversation {
|
||||
|
||||
|
||||
.conversation__content {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.conversation_reply,
|
||||
.icon-button {
|
||||
&:hover {
|
||||
color: $ui-highlight-color;
|
||||
background: mix($ui-base-color, $ui-secondary-color);
|
||||
}
|
||||
}
|
||||
|
||||
.conversation_reply,
|
||||
.icon-button,
|
||||
.status__action-bar-dropdown {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
width: 18em;
|
||||
height: 3.2em;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.conversations_list {
|
||||
@extend .fixed-box;
|
||||
right: $messagingBoxWidth + 2em;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 0.5em;
|
||||
overflow-x: auto;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.conversation-item {
|
||||
float: right;
|
||||
width: 20em;
|
||||
margin-left: 2em;
|
||||
padding: 1em;
|
||||
border-radius: 15px;
|
||||
border: 3px solid $classic-primary-color;
|
||||
-moz-border-radius-bottomleft: 0;
|
||||
-moz-border-radius-bottomright: 0;
|
||||
background: $classic-base-color;
|
||||
|
||||
|
||||
&.has-new-message {
|
||||
background: $ui-highlight-color;
|
||||
color: $classic-primary-color;
|
||||
}
|
||||
|
||||
&.is-focused {
|
||||
border-color: $ui-base-color;
|
||||
}
|
||||
|
||||
.username {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.conversation-stream,
|
||||
.conversation_input {
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
.conversation-stream,
|
||||
.conversation_input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
background: $classic-base-color;
|
||||
color: $ui-base-color;
|
||||
float: right;
|
||||
padding: 0 1em;
|
||||
margin-left: 1em;
|
||||
border: 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
|
||||
.conversation-stream {
|
||||
padding-top: 1em;
|
||||
height: 5em;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
|
||||
|
||||
.message {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.messages >
|
||||
.message {
|
||||
-webkit-border-radius: 0.5rem;
|
||||
-moz-border-radius: 0.5rem;
|
||||
border-radius: 0.5rem;
|
||||
margin-bottom: 0.5em;
|
||||
padding: 0.5em 1em;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ours {
|
||||
text-align: right;
|
||||
background: $light-text-color;
|
||||
float: right;
|
||||
|
||||
.arrow-down {
|
||||
border-top-color: $light-text-color;
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.theirs {
|
||||
text-align: left;
|
||||
background: $ui-highlight-color;
|
||||
float: left;
|
||||
|
||||
.arrow-down {
|
||||
border-top-color: $ui-highlight-color;
|
||||
right: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.arrow-down {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 20px solid transparent;
|
||||
border-top: 20px solid $classic-primary-color;
|
||||
position: relative;
|
||||
bottom: -1em;
|
||||
|
||||
}
|
||||
}
|
54
app/javascript/styles/mastodon/messaging/messaging.scss
Normal file
54
app/javascript/styles/mastodon/messaging/messaging.scss
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
.status-direct,
|
||||
.item-list .conversation {
|
||||
@extend .airmail-border;
|
||||
}
|
||||
|
||||
.main-instant-messaging {
|
||||
|
||||
.column-header__icon {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.messaging-box {
|
||||
@extend .fixed-box;
|
||||
|
||||
right: 1em;
|
||||
width: $messagingBoxWidth;
|
||||
background: $ui-base-color;
|
||||
height: 4em;
|
||||
color: white;
|
||||
z-index: 10;
|
||||
|
||||
&.active {
|
||||
height: $messagingBoxHeight;
|
||||
}
|
||||
|
||||
.messager-textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: white;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.toggle-list {
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
background: $ui-primary-color;
|
||||
border: 0;
|
||||
padding: .5em;
|
||||
width: 2em;
|
||||
|
||||
&.active {
|
||||
background: $highlight-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.conversation_created-at {
|
||||
margin-right: 1em;
|
||||
}
|
@ -1,7 +1,12 @@
|
||||
# Instant messaging documentation - by Tykayn
|
||||
=========
|
||||
here is detailed the progress and the state of wondering.
|
||||
By now, the IM (Instant messaging) aims to be a simple frontend over the direct message structure.
|
||||
By now, **the IM (Instant messaging) aims to be a simple frontend over the direct message structure**.
|
||||
|
||||
Come discuss here:
|
||||
[@tykayn](https://mastodon.cipherbliss.com/@tykayn)
|
||||
or here
|
||||
[contact@cipherbliss.com](mailto:contact@cipherbliss.com)
|
||||
|
||||
## what is done
|
||||
The IM is able to
|
||||
@ -9,15 +14,23 @@ The IM is able to
|
||||
* retrieving contacts from the DB
|
||||
* talk one to one with an account
|
||||
* the input is a simplified compose form, it has predefined settings to have only one recipient. It uses the same mecanism than the compose form to send a private / direct message to somebody. other mentions of persons are not yet recognised.
|
||||
* components used by the IM are listed under the folder `app/javascript/mastodon/features/ui/components/messaging`
|
||||
|
||||
* the addition of bulma CSS enables a reliable set of css classes to have a cool layout and tooling.
|
||||
* style dedicated to the IM is added in the mastodon style folder
|
||||
`app/javascript/styles/mastodon/messaging/main.scss`
|
||||
|
||||
|
||||
# TODO
|
||||
## Work in progress
|
||||
* retrieve contacts, just like in http://localhost:3000/web/accounts/1/following
|
||||
* open a new conversation when we click on an account in the contact list
|
||||
|
||||
## Research
|
||||
find how it is already done to:
|
||||
* retrieve contacts
|
||||
* retrieve a conversation
|
||||
|
||||
|
||||
* retrieve a conversation like http://localhost:3000/web/statuses/103356660630283894
|
||||
* subscribe to the new messages of a conversation
|
||||
* send a direct message
|
||||
* display a page with the routing system
|
||||
|
Loading…
Reference in New Issue
Block a user