Make adjustments and fixes to DEV Conncect (#427)
* Make adjustments and fixes to DEV Conncect * Make various small changes and add settings icon
This commit is contained in:
parent
05fa2527d9
commit
7d018f049e
17 changed files with 156 additions and 30 deletions
|
|
@ -101,6 +101,15 @@
|
|||
flex-grow: 3;
|
||||
}
|
||||
|
||||
.activechatchannel__header{
|
||||
border-bottom: 1px solid $light-medium-gray;
|
||||
padding: 10px 12px;
|
||||
font-weight: bold;
|
||||
font-size:14px;
|
||||
background: $light-gray;
|
||||
a{color: $black}
|
||||
}
|
||||
|
||||
.activechatchannel__messages {
|
||||
font-size: 15px;
|
||||
padding: 10px 0px;
|
||||
|
|
@ -263,6 +272,50 @@
|
|||
padding-bottom: 25px;
|
||||
}
|
||||
|
||||
.chatchannels__channelslistfooter{
|
||||
font-size: 12px;
|
||||
color: $medium-gray;
|
||||
padding: 10px;
|
||||
opacity:0.8;
|
||||
}
|
||||
|
||||
.chatchannels__config{
|
||||
position: absolute;
|
||||
bottom: -14px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: $lightest-gray;
|
||||
border-top: 1px solid $light-medium-gray;
|
||||
padding: 8px 10px 20px;
|
||||
font-weight: bold;
|
||||
padding-left: 16px;
|
||||
cursor: pointer;
|
||||
img{
|
||||
opacity:0.6;
|
||||
}
|
||||
&:hover{
|
||||
.chatchannels__configmenu{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
.chatchannels__configmenu{
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: 42px;
|
||||
padding: 12px 10px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: $lightest-gray;
|
||||
border-top: 1px solid $light-medium-gray;
|
||||
font-size: 13px;
|
||||
a {
|
||||
color: $dark-gray;
|
||||
display: block;
|
||||
padding: 5px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.chatchannels__misc {
|
||||
height: 70px;
|
||||
border-top: 1px solid #c9c9c9
|
||||
|
|
|
|||
|
|
@ -75,17 +75,25 @@ export function conductModeration(
|
|||
export function getChannels(query,retrievalID, props, successCb, failureCb) {
|
||||
const client = algoliasearch(props.algoliaId, props.algoliaKey);
|
||||
const index = client.initIndex(props.algoliaIndex);
|
||||
console.log("first")
|
||||
console.log(query)
|
||||
index.search(query,{
|
||||
hitsPerPage: 100,
|
||||
hitsPerPage: 30,
|
||||
})
|
||||
.then(function(content) {
|
||||
console.log("second")
|
||||
console.log(query)
|
||||
let channels = content.hits
|
||||
if (retrievalID === null || content.hits.filter(e => e.id === retrievalID).length === 1) {
|
||||
successCb(channels)
|
||||
console.log("third-1")
|
||||
console.log(query)
|
||||
successCb(channels, query)
|
||||
} else {
|
||||
index.getObjects([`${retrievalID}`], function(err, content) {
|
||||
console.log("third-2")
|
||||
console.log(query)
|
||||
channels.unshift(content.results[0]);
|
||||
successCb(channels);
|
||||
successCb(channels, query);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { h } from 'preact';
|
||||
import PropTypes from 'prop-types';
|
||||
import ConfigImage from 'images/three-dots.svg';
|
||||
|
||||
const Channels = ({ activeChannelId, chatChannels, handleSwitchChannel }) => {
|
||||
const channels = chatChannels.map(channel => {
|
||||
|
|
@ -36,6 +37,8 @@ const Channels = ({ activeChannelId, chatChannels, handleSwitchChannel }) => {
|
|||
<span
|
||||
data-channel-slug={modififedSlug}
|
||||
className={"chatchanneltabindicator chatchanneltabindicator--" + newMessagesIndicatorClass}
|
||||
data-channel-id={channel.id}
|
||||
data-channel-slug={modififedSlug}
|
||||
>
|
||||
{indicatorPic}
|
||||
</span> {name}
|
||||
|
|
@ -43,10 +46,24 @@ const Channels = ({ activeChannelId, chatChannels, handleSwitchChannel }) => {
|
|||
</button>
|
||||
);
|
||||
});
|
||||
|
||||
let channelsListFooter = ""
|
||||
if (channels.length === 30) {
|
||||
channelsListFooter = <div className="chatchannels__channelslistfooter">You may connect devs you mutually follow. Use the filter to discover all your channels.</div>
|
||||
}
|
||||
console.log(ConfigImage)
|
||||
return (
|
||||
<div className="chatchannels">
|
||||
<div className="chatchannels__channelslist">{channels}</div>
|
||||
<div className="chatchannels__channelslist">
|
||||
{channels}
|
||||
{channelsListFooter}
|
||||
</div>
|
||||
<div className="chatchannels__config">
|
||||
<img src={ConfigImage} style={{height: "18px"}}/>
|
||||
<div className="chatchannels__configmenu">
|
||||
<a href="/settings">DEV Settings</a>
|
||||
<a href="/report-abuse">Report Abuse</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ export default class Chat extends Component {
|
|||
showAlert: false,
|
||||
chatChannels,
|
||||
activeChannelId: chatOptions.activeChannelId,
|
||||
activeChannel: null,
|
||||
showChannelsList: chatOptions.showChannelsList,
|
||||
showTimestamp: chatOptions.showTimestamp,
|
||||
notificationsPermission: null,
|
||||
|
|
@ -63,7 +64,9 @@ export default class Chat extends Component {
|
|||
null,
|
||||
);
|
||||
}
|
||||
this.setState({notificationsPermission: getNotificationState()});
|
||||
this.setState({
|
||||
notificationsPermission: getNotificationState(),
|
||||
});
|
||||
if (this.state.showChannelsList) {
|
||||
getChannels('', this.state.activeChannelId, this.props, this.loadChannels);
|
||||
}
|
||||
|
|
@ -85,17 +88,29 @@ export default class Chat extends Component {
|
|||
this.setState({activeContent: {type_of: "code_editor"}})
|
||||
}
|
||||
|
||||
loadChannels = channels => {
|
||||
this.setState({chatChannels: channels});
|
||||
if (this.state.activeChannelId) {
|
||||
filterForActiveChannel = (channels, id) => {
|
||||
return channels.filter(channel => channel.id === parseInt(id))[0]
|
||||
}
|
||||
|
||||
loadChannels = (channels, query) => {
|
||||
if (this.state.activeChannelId && query.length === 0) {
|
||||
this.setupChannel(this.state.activeChannelId);
|
||||
this.setState({
|
||||
chatChannels: channels,
|
||||
activeChannel: this.filterForActiveChannel(channels, this.state.activeChannelId)
|
||||
});
|
||||
} if (this.state.activeChannelId) {
|
||||
this.setupChannel(this.state.activeChannelId);
|
||||
this.setState({
|
||||
chatChannels: channels
|
||||
});
|
||||
} else {
|
||||
this.setState({chatChannels: channels});
|
||||
const channel = channels[0]
|
||||
const channelSlug = channel.channel_type === 'direct' ?
|
||||
'@'+channel.slug.replace(`${window.currentUser.username}/`, '').replace(`/${window.currentUser.username}`, '') :
|
||||
channel.slug
|
||||
this.triggerSwitchChannel(channel.id, channelSlug)
|
||||
this.setupChannel(channel.id)
|
||||
}
|
||||
channels.forEach((channel, index) => {
|
||||
if ( index < 3 ) {
|
||||
|
|
@ -242,18 +257,24 @@ export default class Chat extends Component {
|
|||
};
|
||||
|
||||
handleSwitchChannel = e => {
|
||||
|
||||
e.preventDefault();
|
||||
this.triggerSwitchChannel(e.target.dataset.channelId, e.target.dataset.channelSlug);
|
||||
let target = e.target;
|
||||
if (!target.dataset.channelId) {
|
||||
target = target.parentElement
|
||||
}
|
||||
this.triggerSwitchChannel(target.dataset.channelId, target.dataset.channelSlug);
|
||||
};
|
||||
|
||||
triggerSwitchChannel = (id, slug) => {
|
||||
this.setupChannel(id);
|
||||
this.setState({
|
||||
activeChannel: this.filterForActiveChannel(this.state.chatChannels, id),
|
||||
activeChannelId: parseInt(id),
|
||||
scrolled: false,
|
||||
showAlert: false,
|
||||
activeContent: null
|
||||
});
|
||||
this.setupChannel(id);
|
||||
window.history.replaceState(null, null, "/connect/"+slug);
|
||||
if (!this.state.isMobileDevice) {
|
||||
document.getElementById("messageform").focus();
|
||||
|
|
@ -333,10 +354,18 @@ export default class Chat extends Component {
|
|||
};
|
||||
|
||||
renderMessages = () => {
|
||||
const { activeChannelId, messages, showTimestamp } = this.state;
|
||||
const { activeChannelId, messages, showTimestamp, activeChannel } = this.state;
|
||||
if (!messages[activeChannelId]) {
|
||||
return
|
||||
}
|
||||
if (messages[activeChannelId].length === 0 && activeChannel ) {
|
||||
const channelUsername = activeChannel.slug.replace(`${window.currentUser.username}/`, '').replace(`/${window.currentUser.username}`, '')
|
||||
return <div className="chatmessage" style={{color: "grey"}}>
|
||||
<div className="chatmessage__body">
|
||||
You and <a href={"/"+channelUsername} style={{color:activeChannel.channel_users[channelUsername].darker_color}} >@{channelUsername}</a> are connected because follow each other. All interactions <em><b>must</b></em> abide by the <a href="/code-of-conduct">code of conduct</a>.
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
return messages[activeChannelId].map(message => (
|
||||
<Message
|
||||
user={message.username}
|
||||
|
|
@ -384,9 +413,10 @@ export default class Chat extends Component {
|
|||
return '';
|
||||
};
|
||||
|
||||
renderActiveChatChannel = () => (
|
||||
renderActiveChatChannel = (channelHeader) => (
|
||||
<div className="activechatchannel">
|
||||
<div className="activechatchannel__conversation">
|
||||
{channelHeader}
|
||||
<div className="activechatchannel__messages" id="messagelist">
|
||||
{this.renderMessages()}
|
||||
<div className="messagelist__sentinel" id="messagelist__sentinel" />
|
||||
|
|
@ -398,6 +428,7 @@ export default class Chat extends Component {
|
|||
<Compose
|
||||
handleSubmitOnClick={this.handleSubmitOnClick}
|
||||
handleKeyDown={this.handleKeyDown}
|
||||
activeChannelId={this.state.activeChannelId}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -413,11 +444,27 @@ export default class Chat extends Component {
|
|||
|
||||
|
||||
render() {
|
||||
let channelHeader = ''
|
||||
let channelHeaderInner = ''
|
||||
const currentChannel = this.state.activeChannel
|
||||
if (currentChannel) {
|
||||
let channelHeaderInner = ''
|
||||
if (currentChannel.channel_type === "direct") {
|
||||
const username = currentChannel.slug.replace(`${window.currentUser.username}/`, '').replace(`/${window.currentUser.username}`, '');
|
||||
channelHeaderInner = <a href={'/'+username}>@{username}</a>
|
||||
}
|
||||
else {
|
||||
channelHeaderInner = currentChannel.channel_name;
|
||||
}
|
||||
channelHeader = <div className="activechatchannel__header">
|
||||
{channelHeaderInner}
|
||||
</div>
|
||||
}
|
||||
return (
|
||||
<div className="chat">
|
||||
{this.renderChatChannels()}
|
||||
<div className="chat__activechat">
|
||||
{this.renderActiveChatChannel()}
|
||||
{this.renderActiveChatChannel(channelHeader)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ export default class Chat extends Component {
|
|||
static propTypes = {
|
||||
handleKeyDown: PropTypes.func.isRequired,
|
||||
handleSubmitOnClick: PropTypes.func.isRequired,
|
||||
activeChannelId: PropTypes.number
|
||||
};
|
||||
|
||||
shouldComponentUpdate() {
|
||||
return false;
|
||||
shouldComponentUpdate(nextProps) {
|
||||
return this.props.activeChannelId != nextProps.activeChannelId;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class Follow < ApplicationRecord
|
|||
if followable_type == "User" && followable.following?(follower)
|
||||
follower.chat_channels.
|
||||
where("slug LIKE ? OR slug like ?", "%/#{followable.username}%", "%#{followable.username}/%").
|
||||
first.update(status:"inactive")
|
||||
first.update(status: "inactive")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class Message < ApplicationRecord
|
|||
end
|
||||
|
||||
def determine_user_validity
|
||||
raise unless chat_channel.has_member?(user) || chat_channel.channel_type == "open"
|
||||
raise unless chat_channel.status == "active" && (chat_channel.has_member?(user) || chat_channel.channel_type == "open")
|
||||
end
|
||||
|
||||
def send_push
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<% end %>
|
||||
</h2>
|
||||
<div class="button-container">
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" class="cta cta-button" data-no-instant>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" class="cta cta-button" data-no-instant>
|
||||
TWITTER
|
||||
</a>
|
||||
<a href="/users/auth/github?state=in-feed-cta" class="cta cta-button" data-no-instant>
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
</header>
|
||||
<div class="widget-body">
|
||||
<center style="margin-bottom: 2px;">
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" class="cta cta-button login-cta-button" data-no-instant>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" class="cta cta-button login-cta-button" data-no-instant>
|
||||
SIGN IN VIA TWITTER
|
||||
</a>
|
||||
<a href="/users/auth/github?state=navbar_basic" class="cta cta-button login-cta-button" data-no-instant>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<div class="new-article-pitch">
|
||||
<h1>Sign In or Create Your Account</h1>
|
||||
<div class="links">
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" class="sign-up-link" data-no-instant>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" class="sign-up-link" data-no-instant>
|
||||
<%= icon("twitter") %> Auth with Twitter
|
||||
</a>
|
||||
<a href="/users/auth/github?state=join-club-page_basic" class="sign-up-link" data-no-instant>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<p>* * *</p>
|
||||
<h2>Please sign in</h2>
|
||||
<br/>
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" class="sign-up-link" data-no-instant><span class="sign-up-text"><img src="<%= asset_url("nerd-emoji.png") %>" alt="nerd emoji" /> Sign in with Twitter</span></a>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" class="sign-up-link" data-no-instant><span class="sign-up-text"><img src="<%= asset_url("nerd-emoji.png") %>" alt="nerd emoji" /> Sign in with Twitter</span></a>
|
||||
<p>or</p>
|
||||
<a href="/users/auth/github" class="sign-up-link" data-no-instant><span class="sign-up-text github-text"><img src="<%= asset_url("nerd-emoji.png") %>" alt="nerd emoji" /> Sign in with Github</span></a>
|
||||
</center>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
Sign In/Up
|
||||
</div>
|
||||
</a>
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" data-no-instant>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" data-no-instant>
|
||||
<div class="option">
|
||||
Via Twitter
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<p>
|
||||
We’re a place where coders share, stay up-to-date and grow their careers.
|
||||
</p>
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" class="sign-up-link cta" data-no-instant>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" class="sign-up-link cta" data-no-instant>
|
||||
<img src="<%= asset_path("twitter-logo.svg") %>" class="icon-img" alt="Twitter"/> Auth With Twitter
|
||||
</a>
|
||||
<a href="/users/auth/github?state=signup-modal" class="sign-up-link cta" data-no-instant>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<hr/>
|
||||
Authenticate via
|
||||
<center>
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" class="sign-up-link" data-no-instant><%= image_tag("twitter-logo.svg", class:"icon-img", alt: "twitter logo") %> Twitter</a>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" class="sign-up-link" data-no-instant><%= image_tag("twitter-logo.svg", class:"icon-img", alt: "twitter logo") %> Twitter</a>
|
||||
or
|
||||
<a href="/users/auth/github?state=notifications-cue_<%= version %>" class="sign-up-link" data-no-instant><%= image_tag("github-logo.svg", class:"icon-img", alt: "github logo") %> GitHub</a>
|
||||
</center>
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
Create your account to customize your feed and start participating.
|
||||
</p>
|
||||
<center>
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" class="sign-up-link" data-no-instant><%= image_tag("twitter-logo.svg", class:"icon-img", alt: "twitter logo") %> Twitter</a>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" class="sign-up-link" data-no-instant><%= image_tag("twitter-logo.svg", class:"icon-img", alt: "twitter logo") %> Twitter</a>
|
||||
or
|
||||
<a href="/users/auth/github?state=notifications-cue_<%= version %>" class="sign-up-link" data-no-instant><%= image_tag("github-logo.svg", class:"icon-img", alt: "github logo") %> GitHub</a>
|
||||
</center>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
<h2>Scope</h2>
|
||||
<p>This Code of Conduct applies both online and in public spaces when an individual is representing the community. Examples of representing a community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of the community may be further defined and clarified by moderators.</p>
|
||||
<h2>Enforcement</h2>
|
||||
<p>Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the team at <a href="mailto:yo@dev.to">yo@dev.to</a>. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The moderation team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.</p>
|
||||
<p>Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the team via the <a href="/report-abuse">abuse report form</a> at <a href="mailto:yo@dev.to">yo@dev.to</a>. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The moderation team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.</p>
|
||||
<p>Moderators who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the community's leadership.</p>
|
||||
<h2>Attribution</h2>
|
||||
<p>This Code of Conduct is adapted from the <a href="http://contributor-covenant.org">Contributor Covenant</a>, version 1.4, available at <a href="http://contributor-covenant.org/version/1/4/">http://contributor-covenant.org/version/1/4</a>.</p>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<img style="width:30px; display:inline;" src="<%= asset_path("emoji/emoji-sparkling-heart.png") %>" />
|
||||
<img style="width:30px; display:inline;" src="<%= asset_path("emoji/emoji-sparkling-heart.png") %>" />
|
||||
<h2>Sign in to get your membership </h2>
|
||||
<a href="/users/auth/twitter?callback_url=https://dev.to/users/auth/twitter/callback" class="cta cta-button" data-no-instant>
|
||||
<a href="/users/auth/twitter?callback_url=<%= ENV["APP_PROTOCOL"] %><%= ENV["APP_DOMAIN"] %>/users/auth/twitter/callback" class="cta cta-button" data-no-instant>
|
||||
TWITTER
|
||||
</a>
|
||||
<a href="/users/auth/github?state=membership-cta" class="cta cta-button" data-no-instant>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ default: &default
|
|||
|
||||
# Additional paths webpack should lookup modules
|
||||
# ['app/assets', 'engine/foo/app/assets']
|
||||
resolved_paths: []
|
||||
resolved_paths: ['app/assets']
|
||||
|
||||
# Reload manifest.json on all requests so we reload latest compiled packs
|
||||
cache_manifest: false
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue