Browse Source

Remove avatars from frontend

pull/241/head
Jannik Volkland 5 years ago
parent
commit
146e6d342c
  1. 11
      webroot/js/app-standalone-chat.js
  2. 11
      webroot/js/app.js
  3. 10
      webroot/js/components/chat/chat.js
  4. 19
      webroot/js/components/chat/message.js
  5. 16
      webroot/js/components/chat/username.js
  6. 1
      webroot/js/utils/constants.js
  7. 10
      webroot/js/utils/helpers.js
  8. 16
      webroot/styles/chat.css
  9. 8
      webroot/styles/standalone-chat.css

11
webroot/js/app-standalone-chat.js

@ -4,8 +4,8 @@ const html = htm.bind(h);
import Chat from './components/chat/chat.js'; import Chat from './components/chat/chat.js';
import Websocket from './utils/websocket.js'; import Websocket from './utils/websocket.js';
import { getLocalStorage, generateAvatar, generateUsername } from './utils/helpers.js'; import { getLocalStorage, generateUsername } from './utils/helpers.js';
import { KEY_USERNAME, KEY_AVATAR } from './utils/constants.js'; import { KEY_USERNAME } from './utils/constants.js';
export default class StandaloneChat extends Component { export default class StandaloneChat extends Component {
constructor(props, context) { constructor(props, context) {
@ -15,28 +15,25 @@ export default class StandaloneChat extends Component {
websocket: new Websocket(), websocket: new Websocket(),
chatEnabled: true, // always true for standalone chat chatEnabled: true, // always true for standalone chat
username: getLocalStorage(KEY_USERNAME) || generateUsername(), username: getLocalStorage(KEY_USERNAME) || generateUsername(),
userAvatarImage: getLocalStorage(KEY_AVATAR) || generateAvatar(`${this.username}${Date.now()}`),
}; };
this.websocket = null; this.websocket = null;
this.handleUsernameChange = this.handleUsernameChange.bind(this); this.handleUsernameChange = this.handleUsernameChange.bind(this);
} }
handleUsernameChange(newName, newAvatar) { handleUsernameChange(newName) {
this.setState({ this.setState({
username: newName, username: newName,
userAvatarImage: newAvatar,
}); });
} }
render(props, state) { render(props, state) {
const { username, userAvatarImage, websocket } = state; const { username, websocket } = state;
return ( return (
html` html`
<${Chat} <${Chat}
websocket=${websocket} websocket=${websocket}
username=${username} username=${username}
userAvatarImage=${userAvatarImage}
messagesOnly messagesOnly
/> />
` `

11
webroot/js/app.js

@ -14,7 +14,6 @@ import {
classNames, classNames,
clearLocalStorage, clearLocalStorage,
debounce, debounce,
generateAvatar,
generateUsername, generateUsername,
getLocalStorage, getLocalStorage,
pluralize, pluralize,
@ -22,7 +21,6 @@ import {
} from './utils/helpers.js'; } from './utils/helpers.js';
import { import {
HEIGHT_SHORT_WIDE, HEIGHT_SHORT_WIDE,
KEY_AVATAR,
KEY_CHAT_DISPLAYED, KEY_CHAT_DISPLAYED,
KEY_USERNAME, KEY_USERNAME,
MESSAGE_OFFLINE, MESSAGE_OFFLINE,
@ -50,9 +48,6 @@ export default class App extends Component {
displayChat: chatStorage === null ? true : chatStorage, displayChat: chatStorage === null ? true : chatStorage,
chatInputEnabled: false, // chat input box state chatInputEnabled: false, // chat input box state
username: getLocalStorage(KEY_USERNAME) || generateUsername(), username: getLocalStorage(KEY_USERNAME) || generateUsername(),
userAvatarImage:
getLocalStorage(KEY_AVATAR) ||
generateAvatar(`${this.username}${Date.now()}`),
configData: {}, configData: {},
extraUserContent: '', extraUserContent: '',
@ -282,10 +277,9 @@ export default class App extends Component {
} }
handleUsernameChange(newName, newAvatar) { handleUsernameChange(newName) {
this.setState({ this.setState({
username: newName, username: newName,
userAvatarImage: newAvatar,
}); });
} }
@ -330,7 +324,6 @@ export default class App extends Component {
playerActive, playerActive,
streamOnline, streamOnline,
streamStatusMessage, streamStatusMessage,
userAvatarImage,
username, username,
viewerCount, viewerCount,
websocket, websocket,
@ -415,7 +408,6 @@ export default class App extends Component {
> >
<${UsernameForm} <${UsernameForm}
username=${username} username=${username}
userAvatarImage=${userAvatarImage}
handleUsernameChange=${this.handleUsernameChange} handleUsernameChange=${this.handleUsernameChange}
/> />
<button <button
@ -499,7 +491,6 @@ export default class App extends Component {
<${Chat} <${Chat}
websocket=${websocket} websocket=${websocket}
username=${username} username=${username}
userAvatarImage=${userAvatarImage}
chatInputEnabled=${chatInputEnabled} chatInputEnabled=${chatInputEnabled}
/> />
</div> </div>

10
webroot/js/components/chat/chat.js

@ -43,14 +43,14 @@ export default class Chat extends Component {
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
const { username: prevName } = prevProps; const { username: prevName } = prevProps;
const { username, userAvatarImage } = this.props; const { username } = this.props;
const { messages: prevMessages } = prevState; const { messages: prevMessages } = prevState;
const { messages } = this.state; const { messages } = this.state;
// if username updated, send a message // if username updated, send a message
if (prevName !== username) { if (prevName !== username) {
this.sendUsernameChange(prevName, username, userAvatarImage); this.sendUsernameChange(prevName, username);
} }
// scroll to bottom of messages list when new ones come in // scroll to bottom of messages list when new ones come in
if (messages.length > prevMessages.length) { if (messages.length > prevMessages.length) {
@ -94,12 +94,11 @@ export default class Chat extends Component {
}); });
} }
sendUsernameChange(oldName, newName, image) { sendUsernameChange(oldName, newName) {
const nameChange = { const nameChange = {
type: SOCKET_MESSAGE_TYPES.NAME_CHANGE, type: SOCKET_MESSAGE_TYPES.NAME_CHANGE,
oldName, oldName,
newName, newName,
image,
}; };
this.websocket.send(nameChange); this.websocket.send(nameChange);
} }
@ -145,11 +144,10 @@ export default class Chat extends Component {
if (!content) { if (!content) {
return; return;
} }
const { username, userAvatarImage } = this.props; const { username } = this.props;
const message = { const message = {
body: content, body: content,
author: username, author: username,
image: userAvatarImage,
type: SOCKET_MESSAGE_TYPES.CHAT, type: SOCKET_MESSAGE_TYPES.CHAT,
}; };
this.websocket.send(message); this.websocket.send(message);

19
webroot/js/components/chat/message.js

@ -3,7 +3,6 @@ import htm from '/js/web_modules/htm.js';
const html = htm.bind(h); const html = htm.bind(h);
import { messageBubbleColorForString } from '../../utils/user-colors.js'; import { messageBubbleColorForString } from '../../utils/user-colors.js';
import { generateAvatar } from '../../utils/helpers.js';
import { convertToText } from '../../utils/chat.js'; import { convertToText } from '../../utils/chat.js';
import { SOCKET_MESSAGE_TYPES } from '../../utils/websocket.js'; import { SOCKET_MESSAGE_TYPES } from '../../utils/websocket.js';
@ -12,23 +11,15 @@ export default class Message extends Component {
const { message, username } = props; const { message, username } = props;
const { type } = message; const { type } = message;
if (type === SOCKET_MESSAGE_TYPES.CHAT) { if (type === SOCKET_MESSAGE_TYPES.CHAT) {
const { image, author, body, timestamp } = message; const { author, body, timestamp } = message;
const formattedMessage = formatMessageText(body, username); const formattedMessage = formatMessageText(body, username);
const avatar = image || generateAvatar(author);
const formattedTimestamp = formatTimestamp(timestamp); const formattedTimestamp = formatTimestamp(timestamp);
const authorColor = messageBubbleColorForString(author); const authorColor = messageBubbleColorForString(author);
const avatarBgColor = { backgroundColor: authorColor };
const authorTextColor = { color: authorColor }; const authorTextColor = { color: authorColor };
return ( return (
html` html`
<div class="message flex flex-row items-start p-3"> <div class="message flex flex-row items-start p-3">
<div
class="message-avatar rounded-full flex items-center justify-center mr-3"
style=${avatarBgColor}
>
<img src=${avatar} class="p-1" />
</div>
<div class="message-content text-sm break-words w-full"> <div class="message-content text-sm break-words w-full">
<div class="message-author text-white font-bold" style=${authorTextColor}> <div class="message-author text-white font-bold" style=${authorTextColor}>
${author} ${author}
@ -44,17 +35,11 @@ export default class Message extends Component {
</div> </div>
`); `);
} else if (type === SOCKET_MESSAGE_TYPES.NAME_CHANGE) { } else if (type === SOCKET_MESSAGE_TYPES.NAME_CHANGE) {
const { oldName, newName, image } = message; const { oldName, newName } = message;
return ( return (
html` html`
<div class="message message-name-change flex items-center justify-start p-3"> <div class="message message-name-change flex items-center justify-start p-3">
<div class="message-content flex flex-row items-center justify-center text-sm w-full"> <div class="message-content flex flex-row items-center justify-center text-sm w-full">
<div
class="message-avatar rounded-full mr-3 bg-gray-900"
>
<img class="mr-2 p-1" src=${image} />
</div>
<div class="text-white text-center opacity-50"> <div class="text-white text-center opacity-50">
<span class="font-bold">${oldName}</span> is now known as <span class="font-bold">${newName}</span>. <span class="font-bold">${oldName}</span> is now known as <span class="font-bold">${newName}</span>.
</div> </div>

16
webroot/js/components/chat/username.js

@ -2,8 +2,8 @@ import { h, Component, createRef } from '/js/web_modules/preact.js';
import htm from '/js/web_modules/htm.js'; import htm from '/js/web_modules/htm.js';
const html = htm.bind(h); const html = htm.bind(h);
import { generateAvatar, setLocalStorage } from '../../utils/helpers.js'; import { setLocalStorage } from '../../utils/helpers.js';
import { KEY_USERNAME, KEY_AVATAR } from '../../utils/constants.js'; import { KEY_USERNAME } from '../../utils/constants.js';
export default class UsernameForm extends Component { export default class UsernameForm extends Component {
constructor(props, context) { constructor(props, context) {
@ -47,11 +47,9 @@ export default class UsernameForm extends Component {
let newName = this.textInput.current.value; let newName = this.textInput.current.value;
newName = newName.trim(); newName = newName.trim();
if (newName !== '' && newName !== curName) { if (newName !== '' && newName !== curName) {
const newAvatar = generateAvatar(`${newName}${Date.now()}`);
setLocalStorage(KEY_USERNAME, newName); setLocalStorage(KEY_USERNAME, newName);
setLocalStorage(KEY_AVATAR, newAvatar);
if (handleUsernameChange) { if (handleUsernameChange) {
handleUsernameChange(newName, newAvatar); handleUsernameChange(newName);
} }
this.handleHideForm(); this.handleHideForm();
} }
@ -59,7 +57,7 @@ export default class UsernameForm extends Component {
} }
render(props, state) { render(props, state) {
const { username, userAvatarImage } = props; const { username } = props;
const { displayForm } = state; const { displayForm } = state;
const narrowSpace = document.body.clientWidth < 640; const narrowSpace = document.body.clientWidth < 640;
@ -77,12 +75,6 @@ export default class UsernameForm extends Component {
html` html`
<div id="user-info"> <div id="user-info">
<div id="user-info-display" style=${styles.info} title="Click to update user name" class="flex flex-row justify-end items-center cursor-pointer py-2 px-4 overflow-hidden w-full opacity-1 transition-opacity duration-200 hover:opacity-75" onClick=${this.handleDisplayForm}> <div id="user-info-display" style=${styles.info} title="Click to update user name" class="flex flex-row justify-end items-center cursor-pointer py-2 px-4 overflow-hidden w-full opacity-1 transition-opacity duration-200 hover:opacity-75" onClick=${this.handleDisplayForm}>
<img
src=${userAvatarImage}
alt=""
id="username-avatar"
class="rounded-full bg-black bg-opacity-50 border border-solid border-gray-700 mr-2 h-8 w-8"
/>
<span id="username-display" class="text-indigo-600 text-xs font-semibold truncate overflow-hidden whitespace-no-wrap">${username}</span> <span id="username-display" class="text-indigo-600 text-xs font-semibold truncate overflow-hidden whitespace-no-wrap">${username}</span>
</div> </div>

1
webroot/js/utils/constants.js

@ -22,7 +22,6 @@ export const PLAYER_VOLUME = 'owncast_volume';
export const KEY_USERNAME = 'owncast_username'; export const KEY_USERNAME = 'owncast_username';
export const KEY_AVATAR = 'owncast_avatar';
export const KEY_CHAT_DISPLAYED = 'owncast_chat'; export const KEY_CHAT_DISPLAYED = 'owncast_chat';
export const KEY_CHAT_FIRST_MESSAGE_SENT = 'owncast_first_message_sent'; export const KEY_CHAT_FIRST_MESSAGE_SENT = 'owncast_first_message_sent';
export const CHAT_INITIAL_PLACEHOLDER_TEXT = 'Type here to chat, no account necessary.'; export const CHAT_INITIAL_PLACEHOLDER_TEXT = 'Type here to chat, no account necessary.';

10
webroot/js/utils/helpers.js

@ -92,16 +92,6 @@ export function getOrientation(forTouch = false) {
} }
} }
// generate random avatar from https://robohash.org
export function generateAvatar(hash) {
const avatarSource = 'https://robohash.org/';
const optionSize = '?size=80x80';
const optionSet = '&set=set2';
const optionBg = ''; // or &bgset=bg1 or bg2
return avatarSource + hash + optionSize + optionSet + optionBg;
}
export function generateUsername() { export function generateUsername() {
return `User ${(Math.floor(Math.random() * 42) + 1)}`; return `User ${(Math.floor(Math.random() * 42) + 1)}`;
} }

16
webroot/styles/chat.css

@ -115,22 +115,6 @@
scrollbar-color: var(--category-button-color) black; scrollbar-color: var(--category-button-color) black;
} }
/******************************/
.message-avatar {
height: 3.0em;
width: 3.0em;
}
.message-avatar img {
max-width: unset;
height: 3.0em;
width: 3.0em;
padding: 5px;
}
/* MESSAGE TEXT HTML */ /* MESSAGE TEXT HTML */
/* MESSAGE TEXT HTML */ /* MESSAGE TEXT HTML */
/* MESSAGE TEXT HTML */ /* MESSAGE TEXT HTML */

8
webroot/styles/standalone-chat.css

@ -28,14 +28,6 @@ The styles in this file mostly ovveride those coming from chat.css
#messages-only .message-content { #messages-only .message-content {
text-shadow: 1px 1px 0px rgba(0,0,0,0.25); text-shadow: 1px 1px 0px rgba(0,0,0,0.25);
} }
#messages-only .message-avatar {
display: none;
box-shadow: 0px 0px 3px 0px rgba(0,0,0,0.25);
}
#messages-only .message-avatar img {
height: 1.8em;
width: 1.8em;
}
#messages-only .message { #messages-only .message {
padding: .5em; padding: .5em;
} }

Loading…
Cancel
Save