mirror of
https://github.com/urbit/shrub.git
synced 2024-12-21 01:41:37 +03:00
Merge pull request #2318 from urbit/mp/os1/chat/spinner
chat: add new spinner, behaviours
This commit is contained in:
commit
a0b9e84ae5
@ -108,6 +108,20 @@ h2 {
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
|
||||
/* spinner */
|
||||
|
||||
.spin-active {
|
||||
animation: spin 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {transform: rotate(0deg);}
|
||||
25% {transform: rotate(90deg);}
|
||||
50% {transform: rotate(180deg);}
|
||||
75% {transform: rotate(270deg);}
|
||||
100% {transform: rotate(360deg);}
|
||||
}
|
||||
|
||||
/* embeds */
|
||||
.embed-container {
|
||||
position: relative;
|
||||
|
@ -1,38 +0,0 @@
|
||||
.spinner-pending {
|
||||
position: relative;
|
||||
content: "";
|
||||
border-radius: 100%;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
background-color: rgba(255,255,255,1);
|
||||
}
|
||||
|
||||
.spinner-pending::after {
|
||||
content: "";
|
||||
background-color: rgba(128,128,128,1);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
border-radius: 100%;
|
||||
clip: rect(0, 16px, 16px, 8px);
|
||||
|
||||
animation: spin 1s cubic-bezier(0.745, 0.045, 0.355, 1.000) infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {transform:rotate(0deg)}
|
||||
25% {transform:rotate(90deg)}
|
||||
50% {transform:rotate(180deg)}
|
||||
75% {transform:rotate(270deg)}
|
||||
100% {transform:rotate(360deg)}
|
||||
}
|
||||
|
||||
.spinner-nostart {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 100%;
|
||||
content:'';
|
||||
background-color: black;
|
||||
}
|
||||
|
@ -125,11 +125,11 @@ class UrbitApi {
|
||||
}
|
||||
|
||||
chatViewAction(data) {
|
||||
this.action("chat-view", "json", data);
|
||||
return this.action("chat-view", "json", data);
|
||||
}
|
||||
|
||||
chatViewCreate(path, security, members, allowHistory) {
|
||||
this.chatViewAction({
|
||||
return this.chatViewAction({
|
||||
create: {
|
||||
path, security, members,
|
||||
'allow-history': allowHistory
|
||||
@ -185,6 +185,16 @@ class UrbitApi {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setSpinner(boolean) {
|
||||
store.handleEvent({
|
||||
data: {
|
||||
local: {
|
||||
spinner: boolean
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export let api = new UrbitApi();
|
||||
|
@ -1,23 +1,23 @@
|
||||
import React, { Component } from "react";
|
||||
import classnames from "classnames";
|
||||
import { IconHome } from "/components/lib/icons/icon-home";
|
||||
import { IconSpinner } from "/components/lib/icons/icon-spinner";
|
||||
import { Sigil } from "/components/lib/icons/sigil";
|
||||
|
||||
export class HeaderBar extends Component {
|
||||
render() {
|
||||
// let spin = (this.props.spinner)
|
||||
// ? <div className="absolute"
|
||||
// style={{width: 16, height: 16, top: 16, left: 55}}>
|
||||
// <IconSpinner/>
|
||||
// </div>
|
||||
// : null;
|
||||
|
||||
let popout = window.location.href.includes("popout/")
|
||||
? "dn" : "dn db-m db-l db-xl";
|
||||
|
||||
let title = document.title === "Home" ? "" : document.title;
|
||||
|
||||
let spinner = !!this.props.spinner
|
||||
? this.props.spinner : false;
|
||||
|
||||
let spinnerClasses = "";
|
||||
|
||||
if (spinner === true) {
|
||||
spinnerClasses = "spin-active";
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
@ -28,7 +28,7 @@ export class HeaderBar extends Component {
|
||||
className="dib gray2 f9 inter absolute left-0"
|
||||
href="/"
|
||||
style={{ top: 14 }}>
|
||||
<IconHome />
|
||||
<IconHome classes={spinnerClasses} />
|
||||
<span
|
||||
className="ml2 white-d v-top lh-title"
|
||||
style={{ paddingTop: 3 }}>
|
||||
@ -43,10 +43,14 @@ export class HeaderBar extends Component {
|
||||
}}>
|
||||
{title}
|
||||
</span>
|
||||
{/* {spin} */}
|
||||
<div className="absolute right-0 lh-copy" style={{ top: 12 }}>
|
||||
<Sigil ship={"~" + window.ship} size={16} color={"#000000"} />
|
||||
<span className="mono white-d f9 ml2 v-top">{"~" + window.ship}</span>
|
||||
<div className="absolute right-0 lh-copy" style={{ top: 9 }}>
|
||||
<Sigil
|
||||
ship={"~" + window.ship}
|
||||
size={16}
|
||||
color={"#000000"}
|
||||
classes="v-mid mix-blend-diff"
|
||||
/>
|
||||
<span className="mono white-d f9 ml2">{"~" + window.ship}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -2,10 +2,10 @@ import React, { Component } from "react";
|
||||
|
||||
export class IconHome extends Component {
|
||||
render() {
|
||||
let classes = !!this.props.classes ? this.props.classes : "";
|
||||
return (
|
||||
//TODO relocate to ~launch when OS1 is ported
|
||||
<img
|
||||
className="invert-d"
|
||||
className={"invert-d " + classes}
|
||||
src="/~chat/img/Home.png"
|
||||
width={16}
|
||||
height={16}
|
||||
|
@ -1,9 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
|
||||
export class IconSpinner extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="spinner-pending"></div>
|
||||
);
|
||||
}
|
||||
}
|
@ -145,7 +145,7 @@ export class NewScreen extends Component {
|
||||
group: [],
|
||||
ships: []
|
||||
}, () => {
|
||||
props.setSpinner(true);
|
||||
props.api.setSpinner(true);
|
||||
// if we want a "proper group" that can be managed from the contacts UI,
|
||||
// we make a path of the form /~zod/cool-group
|
||||
// if not, we make a path of the form /~/~zod/free-chat
|
||||
@ -153,10 +153,13 @@ export class NewScreen extends Component {
|
||||
if (!state.createGroup && state.groups.length === 0) {
|
||||
chatPath = `/~${chatPath}`;
|
||||
}
|
||||
props.api.chatView.create(
|
||||
chatPath, state.security, aud, state.allowHistory
|
||||
);
|
||||
props.history.push(`/~chat/room${chatPath}`);
|
||||
let submit = props.api.chatView.create(
|
||||
chatPath, state.security, aud, state.allowHistory
|
||||
);
|
||||
submit.then(() => {
|
||||
props.api.setSpinner(false);
|
||||
props.history.push(`/~chat/room${chatPath}`);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -21,13 +21,6 @@ export class Root extends Component {
|
||||
|
||||
this.state = store.state;
|
||||
store.setStateHandler(this.setState.bind(this));
|
||||
this.setSpinner = this.setSpinner.bind(this);
|
||||
}
|
||||
|
||||
setSpinner(spinner) {
|
||||
this.setState({
|
||||
spinner
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -95,12 +88,11 @@ export class Root extends Component {
|
||||
return (
|
||||
<Skeleton
|
||||
sidebarHideOnMobile={true}
|
||||
spinner={this.state.spinner}
|
||||
spinner={state.spinner}
|
||||
sidebar={renderChannelSidebar(props)}
|
||||
sidebarShown={state.sidebarShown}
|
||||
>
|
||||
<NewScreen
|
||||
setSpinner={this.setSpinner}
|
||||
api={api}
|
||||
inbox={state.inbox || {}}
|
||||
groups={state.groups || {}}
|
||||
@ -124,6 +116,7 @@ export class Root extends Component {
|
||||
|
||||
return (
|
||||
<Skeleton
|
||||
spinner={state.spinner}
|
||||
sidebarHideOnMobile={true}
|
||||
sidebar={renderChannelSidebar(props)}
|
||||
sidebarShown={state.sidebarShown}
|
||||
@ -146,7 +139,7 @@ export class Root extends Component {
|
||||
let sig = props.match.url.includes("/~/");
|
||||
if (sig) {
|
||||
station = '/~' + station;
|
||||
}
|
||||
}
|
||||
let mailbox = state.inbox[station] || {
|
||||
config: {
|
||||
read: 0,
|
||||
@ -164,6 +157,7 @@ export class Root extends Component {
|
||||
return (
|
||||
<Skeleton
|
||||
sidebarHideOnMobile={true}
|
||||
spinner={state.spinner}
|
||||
popout={popout}
|
||||
sidebarShown={state.sidebarShown}
|
||||
sidebar={renderChannelSidebar(props)}
|
||||
@ -197,7 +191,7 @@ export class Root extends Component {
|
||||
let sig = props.match.url.includes("/~/");
|
||||
if (sig) {
|
||||
station = '/~' + station;
|
||||
}
|
||||
}
|
||||
|
||||
let permission = state.permissions[station] || {
|
||||
kind: "",
|
||||
@ -211,6 +205,7 @@ export class Root extends Component {
|
||||
return (
|
||||
<Skeleton
|
||||
sidebarHideOnMobile={true}
|
||||
spinner={state.spinner}
|
||||
sidebarShown={state.sidebarShown}
|
||||
popout={popout}
|
||||
sidebar={renderChannelSidebar(props)}
|
||||
@ -238,7 +233,7 @@ export class Root extends Component {
|
||||
let sig = props.match.url.includes("/~/");
|
||||
if (sig) {
|
||||
station = '/~' + station;
|
||||
}
|
||||
}
|
||||
let group = state.groups[station] || new Set([]);
|
||||
|
||||
let popout = props.match.url.includes("/popout/");
|
||||
@ -246,7 +241,7 @@ export class Root extends Component {
|
||||
return (
|
||||
<Skeleton
|
||||
sidebarHideOnMobile={true}
|
||||
spinner={this.state.spinner}
|
||||
spinner={state.spinner}
|
||||
popout={popout}
|
||||
sidebarShown={state.sidebarShown}
|
||||
sidebar={renderChannelSidebar(props)}
|
||||
@ -254,7 +249,6 @@ export class Root extends Component {
|
||||
<SettingsScreen
|
||||
{...props}
|
||||
station={station}
|
||||
setSpinner={this.setSpinner}
|
||||
api={api}
|
||||
station={station}
|
||||
group={group}
|
||||
|
@ -26,7 +26,7 @@ export class SettingsScreen extends Component {
|
||||
this.setState({
|
||||
isLoading: false
|
||||
}, () => {
|
||||
props.setSpinner(false);
|
||||
props.api.setSpinner(false);
|
||||
props.history.push('/~chat');
|
||||
});
|
||||
}
|
||||
@ -36,7 +36,7 @@ export class SettingsScreen extends Component {
|
||||
const { props, state } = this;
|
||||
|
||||
props.api.chatView.delete(props.station);
|
||||
props.setSpinner(true);
|
||||
props.api.setSpinner(true);
|
||||
|
||||
this.setState({
|
||||
isLoading: true
|
||||
|
@ -5,6 +5,7 @@ export class LocalReducer {
|
||||
let data = _.get(json, 'local', false);
|
||||
if (data) {
|
||||
this.sidebarToggle(data, state);
|
||||
this.setSpinner(data, state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,4 +15,11 @@ export class LocalReducer {
|
||||
state.sidebarShown = obj.sidebarToggle;
|
||||
}
|
||||
}
|
||||
|
||||
setSpinner(obj, state) {
|
||||
let data = _.has(obj, 'spinner', false);
|
||||
if (data) {
|
||||
state.spinner = obj.spinner;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user