mirror of
https://framagit.org/tykayn/mastodon.git
synced 2023-08-25 08:33:12 +02:00
🎨 style on conversations stacks
Signed-off-by: Baptiste Lemoine <contact@cipherbliss.com>
This commit is contained in:
parent
cda3febaac
commit
8dde1abdd4
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { version, source_url } from 'mastodon/initial_state';
|
||||
import { source_url, version } from 'mastodon/initial_state';
|
||||
|
||||
export default class ErrorBoundary extends React.PureComponent {
|
||||
|
||||
@ -10,17 +10,17 @@ export default class ErrorBoundary extends React.PureComponent {
|
||||
};
|
||||
|
||||
state = {
|
||||
hasError: false,
|
||||
stackTrace: undefined,
|
||||
hasError : false,
|
||||
stackTrace : undefined,
|
||||
componentStack: undefined,
|
||||
};
|
||||
|
||||
componentDidCatch (error, info) {
|
||||
componentDidCatch(error, info) {
|
||||
this.setState({
|
||||
hasError: true,
|
||||
stackTrace: error.stack,
|
||||
hasError : true,
|
||||
stackTrace : error.stack,
|
||||
componentStack: info && info.componentStack,
|
||||
copied: false,
|
||||
copied : false,
|
||||
});
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ export default class ErrorBoundary extends React.PureComponent {
|
||||
const { stackTrace } = this.state;
|
||||
const textarea = document.createElement('textarea');
|
||||
|
||||
textarea.textContent = stackTrace;
|
||||
textarea.textContent = stackTrace;
|
||||
textarea.style.position = 'fixed';
|
||||
|
||||
document.body.appendChild(textarea);
|
||||
@ -44,7 +44,7 @@ export default class ErrorBoundary extends React.PureComponent {
|
||||
|
||||
this.setState({ copied: true });
|
||||
setTimeout(() => this.setState({ copied: false }), 700);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { hasError, copied } = this.state;
|
||||
@ -54,13 +54,32 @@ export default class ErrorBoundary extends React.PureComponent {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='error-boundary'>
|
||||
<div>
|
||||
<p className='error-boundary__error'><FormattedMessage id='error.unexpected_crash.explanation' defaultMessage='Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.' /></p>
|
||||
<p><FormattedMessage id='error.unexpected_crash.next_steps' defaultMessage='Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.' /></p>
|
||||
<p className='error-boundary__footer'>Mastodon v{version} · <a href={source_url} rel='noopener noreferrer' target='_blank'><FormattedMessage id='errors.unexpected_crash.report_issue' defaultMessage='Report issue' /></a> · <button onClick={this.handleCopyStackTrace} className={copied && 'copied'}><FormattedMessage id='errors.unexpected_crash.copy_stacktrace' defaultMessage='Copy stacktrace to clipboard' /></button></p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='error-boundary hero text-center padded content'>
|
||||
<div >
|
||||
<p className='error-boundary__error title content-heading'><FormattedMessage
|
||||
id='error.unexpected_crash.explanation'
|
||||
defaultMessage='Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.'
|
||||
/></p >
|
||||
<p className='content'><FormattedMessage
|
||||
id='error.unexpected_crash.next_steps'
|
||||
defaultMessage='Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.'
|
||||
/></p >
|
||||
<p className='error-boundary__footer'>Mastodon v{version} · <a
|
||||
href={source_url}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
><FormattedMessage
|
||||
id='errors.unexpected_crash.report_issue'
|
||||
defaultMessage='Report issue'
|
||||
/></a > · <button
|
||||
onClick={this.handleCopyStackTrace}
|
||||
className={copied && 'copied'}
|
||||
><FormattedMessage
|
||||
id='errors.unexpected_crash.copy_stacktrace'
|
||||
defaultMessage='Copy stacktrace to clipboard'
|
||||
/></button ></p >
|
||||
</div >
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,10 @@ class LinkFooter extends React.PureComponent {
|
||||
var snowClasses = this.props.enableChristmasSnow ? 'snow-button active' : 'snow-button ';
|
||||
const navToTags = HashTagNavlinks.map(element => {
|
||||
return (
|
||||
<li className='tag-element btn-small btn'>
|
||||
<li
|
||||
className='tag-element btn-small btn'
|
||||
key={element}
|
||||
>
|
||||
|
||||
<NavLink
|
||||
exact
|
||||
|
@ -1,21 +1,59 @@
|
||||
import React from 'react';
|
||||
import Contact from './Contact';
|
||||
import PropTypes from 'prop-types';
|
||||
import ConversationStream from './conversation-stream';
|
||||
|
||||
/**
|
||||
* a conversation between the current logged in user and one recipient
|
||||
*/
|
||||
export default class ConversationItem extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
messages : PropTypes.array, // our and their message sorted chronologically
|
||||
recipient : PropTypes.any, // account of the person we talk to, not current logged in account
|
||||
newMessages: PropTypes.number,
|
||||
displayed : PropTypes.bool,
|
||||
};
|
||||
following = [];
|
||||
|
||||
render() {
|
||||
static defaultProps = {
|
||||
newMessages: 0,
|
||||
displayed : true,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
composeMessage: '',
|
||||
displayed : this.props.displayed,
|
||||
};
|
||||
}
|
||||
|
||||
submitCompose() {
|
||||
console.log('submit');
|
||||
}
|
||||
|
||||
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 list = (
|
||||
<li className='conversations_item has-new-message'>
|
||||
<div className='title'>
|
||||
<li className={'conversation-item ' + hasNewClass + ' ' + isVisible}>
|
||||
<div className='top-title'>
|
||||
<i
|
||||
role='img'
|
||||
className='fa fa-envelope column-header__icon fa-fw'
|
||||
/>
|
||||
Un Gens
|
||||
<span className='new-message-counter'>
|
||||
(3)</span >
|
||||
<Contact account={this.props.recipient} />
|
||||
{this.props.newMessages && (
|
||||
<span className='new-message-counter'>
|
||||
({this.props.newMessages})
|
||||
</span >
|
||||
)}
|
||||
<button className='btn-small'>
|
||||
<i
|
||||
role='img'
|
||||
@ -23,24 +61,11 @@ export default class ConversationItem extends React.PureComponent {
|
||||
/>
|
||||
</button >
|
||||
</div >
|
||||
<div className='conversation_stream'>
|
||||
<div className='message theirs'>
|
||||
<p >oh hello there! 😋 </p >
|
||||
<div className='arrow-down' />
|
||||
</div >
|
||||
<div className='message mine'>
|
||||
<p >General Emoji</p >
|
||||
<div className='arrow-down' />
|
||||
</div >
|
||||
<div className='message theirs'>
|
||||
<p >we just achieved comedy</p >
|
||||
<div className='arrow-down' />
|
||||
</div >
|
||||
</div >
|
||||
<ConversationStream messages={this.props.messages} />
|
||||
<div className='conversation_input'>
|
||||
<form
|
||||
action='#'
|
||||
onSubmit={this.submitCompose()}
|
||||
onSubmit={this.submitCompose}
|
||||
>
|
||||
<textarea
|
||||
name='messager'
|
||||
@ -49,6 +74,8 @@ export default class ConversationItem extends React.PureComponent {
|
||||
rows='3'
|
||||
className='messager-textarea'
|
||||
placeholder='allez dis nous tout'
|
||||
value={this.state.composeMessage}
|
||||
onChange={this.handleChange}
|
||||
|
||||
/>
|
||||
<input
|
||||
|
@ -1,12 +1,35 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default class ConversationStream extends React.PureComponent {
|
||||
static propTypes = {
|
||||
messages: PropTypes.array,
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div class='conversation-stream'>
|
||||
ConversationStream todo
|
||||
let messagesLists = (
|
||||
<div className='no_messages'>
|
||||
no messages
|
||||
</div >
|
||||
);
|
||||
|
||||
if (this.props.messages) {
|
||||
|
||||
messagesLists = this.props.messages.map(message => {
|
||||
return (
|
||||
<li className={'message ' + message.text}>
|
||||
<p >{message.text}</p >
|
||||
<div className='arrow-down' />
|
||||
</li >
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
return (
|
||||
<div className='conversation-stream'>
|
||||
<ul className='messages'>
|
||||
{messagesLists}
|
||||
</ul >
|
||||
</div >
|
||||
);
|
||||
}
|
||||
|
@ -1,21 +1,17 @@
|
||||
import React from 'react';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import { mockContactList } from './mockContactList';
|
||||
import Contact from './Contact';
|
||||
import ConversationItem from './conversation-item';
|
||||
|
||||
const following = mockContactList;
|
||||
import { mockRecipient, mockRecipient2 } from './mockConversation';
|
||||
|
||||
export default class ConversationStack extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
following: PropTypes.array,
|
||||
// conversations: PropTypes.array,
|
||||
conversations: PropTypes.array,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
following: following,
|
||||
conversations: [mockRecipient, mockRecipient2],
|
||||
};
|
||||
|
||||
openConversationWith(account) {
|
||||
@ -23,20 +19,26 @@ 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 >
|
||||
),
|
||||
);
|
||||
return (
|
||||
<ul className='stack conversations_list'>
|
||||
{list}
|
||||
</ul >
|
||||
|
||||
return this.props.following.map(elem =>
|
||||
|
||||
(<li className='user-item'>
|
||||
<div className='conversation-box'>
|
||||
<div
|
||||
className='conversation-header'
|
||||
onClick={this.openConversationWith(elem)}
|
||||
>
|
||||
<Contact account={elem} />
|
||||
</div >
|
||||
<ConversationItem />
|
||||
</div >
|
||||
</li >),
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
export const mockMessages = [
|
||||
{ text: 'oh hello there! 😋 ', who: 'theirs' },
|
||||
{ text: 'General Emoji', who: 'ours' },
|
||||
{ text: 'we just achieved comedy', who: 'theirs' },
|
||||
]
|
||||
;
|
||||
export const mockMessages2 = [
|
||||
{ text: 'oh oh oh ', who: 'theirs' },
|
||||
{ text: 'General Emoji', who: 'ours' },
|
||||
{ text: 'DANGER!!', who: 'theirs' },
|
||||
{ text: 'JUST KIDDING WILL ROBINSON.', who: 'theirs' },
|
||||
]
|
||||
;
|
||||
|
||||
export const mockRecipient = [
|
||||
{
|
||||
id : 3,
|
||||
username : 'chuck norris',
|
||||
newMessages: 5,
|
||||
messages : mockMessages,
|
||||
},
|
||||
]
|
||||
;
|
||||
|
||||
export const mockRecipient2 = [
|
||||
{
|
||||
id : 4,
|
||||
username : 'the Bo botte',
|
||||
newMessages: 0,
|
||||
messages : mockMessages2,
|
||||
},
|
||||
]
|
||||
;
|
@ -384,6 +384,22 @@ hr.spacer {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
input {
|
||||
background: auto;
|
||||
}
|
||||
|
||||
hr,
|
||||
.select select,
|
||||
.textarea,
|
||||
.input {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
|
||||
&:hover {
|
||||
border: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.batch-form-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
@ -1,5 +1,6 @@
|
||||
$messagingBoxWidth: 20em;
|
||||
$messagingBoxHeight: 100%;
|
||||
$conversationBoxHeight: 20em;
|
||||
|
||||
.fixed-box {
|
||||
border: solid 1px white;
|
||||
@ -99,20 +100,22 @@ $messagingBoxHeight: 100%;
|
||||
}
|
||||
|
||||
.conversations_list {
|
||||
right: 1em;
|
||||
position: absolute;
|
||||
@extend .fixed-box;
|
||||
right: $messagingBoxWidth + 2em;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 0.5em;
|
||||
background: gray;
|
||||
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.conversation-item {
|
||||
@extend .fixed-box;
|
||||
width: $messagingBoxWidth;
|
||||
right: $messagingBoxWidth + 5em;
|
||||
background: $ui-secondary-color;
|
||||
float: right;
|
||||
width: 20em;
|
||||
margin-left: 2em;
|
||||
padding: 1em;
|
||||
border-radius: 15px;
|
||||
background: $classic-base-color;
|
||||
|
||||
&.has-new-message {
|
||||
background: $ui-highlight-color;
|
||||
@ -126,7 +129,7 @@ $messagingBoxHeight: 100%;
|
||||
|
||||
.conversation_stream {
|
||||
padding-top: 1em;
|
||||
height: $messagingBoxHeight;
|
||||
height: $conversationBoxHeight;
|
||||
overflow: auto;
|
||||
background: $ui-secondary-color;
|
||||
|
||||
|
@ -229,3 +229,7 @@ button {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.padded {
|
||||
padding: 1em;
|
||||
}
|
||||
|
@ -32,25 +32,27 @@
|
||||
|
||||
%hr.spacer/
|
||||
|
||||
.fields-row
|
||||
.fields-row__column.fields-group.fields-row__column-6
|
||||
.input.with_block_label
|
||||
.custom-label-container
|
||||
.fields-group.custom_labels_container
|
||||
.with_block_label
|
||||
%label= t('simple_form.labels.defaults.fields')
|
||||
%span.hint= t('simple_form.hints.defaults.fields')
|
||||
|
||||
= f.simple_fields_for :fields do |fields_f|
|
||||
.row
|
||||
= fields_f.input :name, placeholder: t('simple_form.labels.account.fields.name'), input_html: { maxlength: 255 }
|
||||
= fields_f.input :value, placeholder: t('simple_form.labels.account.fields.value'), input_html: { maxlength: 255 }
|
||||
.columns
|
||||
.column.tag-side
|
||||
= fields_f.input :name, placeholder: t('simple_form.labels.account.fields.name'), input_html: { maxlength: 255 }
|
||||
.column.value-side
|
||||
= fields_f.input :value, placeholder: t('simple_form.labels.account.fields.value'), input_html: { maxlength: 255 }
|
||||
|
||||
.fields-row__column.fields-group.fields-row__column-6
|
||||
%h6= t('verification.verification')
|
||||
%p.hint= t('verification.explanation_html')
|
||||
.fields-group.verification-container
|
||||
%h6= t('verification.verification')
|
||||
%p.hint= t('verification.explanation_html')
|
||||
|
||||
.input-copy
|
||||
.input-copy__wrapper
|
||||
%input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: link_to('Mastodon', ActivityPub::TagManager.instance.url_for(@account), rel: 'me').to_str }
|
||||
%button{ type: :button }= t('generic.copy')
|
||||
.input-copy
|
||||
.input-copy__wrapper
|
||||
%input{ type: :text, maxlength: '999', spellcheck: 'false', readonly: 'true', value: link_to('Mastodon', ActivityPub::TagManager.instance.url_for(@account), rel: 'me').to_str }
|
||||
%button{ type: :button }= t('generic.copy')
|
||||
|
||||
.actions
|
||||
= f.button :button, t('generic.save_changes'), type: :submit
|
||||
|
Loading…
Reference in New Issue
Block a user