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;
|
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 */
|
/* embeds */
|
||||||
.embed-container {
|
.embed-container {
|
||||||
position: relative;
|
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) {
|
chatViewAction(data) {
|
||||||
this.action("chat-view", "json", data);
|
return this.action("chat-view", "json", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
chatViewCreate(path, security, members, allowHistory) {
|
chatViewCreate(path, security, members, allowHistory) {
|
||||||
this.chatViewAction({
|
return this.chatViewAction({
|
||||||
create: {
|
create: {
|
||||||
path, security, members,
|
path, security, members,
|
||||||
'allow-history': allowHistory
|
'allow-history': allowHistory
|
||||||
@ -185,6 +185,16 @@ class UrbitApi {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSpinner(boolean) {
|
||||||
|
store.handleEvent({
|
||||||
|
data: {
|
||||||
|
local: {
|
||||||
|
spinner: boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export let api = new UrbitApi();
|
export let api = new UrbitApi();
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import classnames from "classnames";
|
import classnames from "classnames";
|
||||||
import { IconHome } from "/components/lib/icons/icon-home";
|
import { IconHome } from "/components/lib/icons/icon-home";
|
||||||
import { IconSpinner } from "/components/lib/icons/icon-spinner";
|
|
||||||
import { Sigil } from "/components/lib/icons/sigil";
|
import { Sigil } from "/components/lib/icons/sigil";
|
||||||
|
|
||||||
export class HeaderBar extends Component {
|
export class HeaderBar extends Component {
|
||||||
render() {
|
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/")
|
let popout = window.location.href.includes("popout/")
|
||||||
? "dn" : "dn db-m db-l db-xl";
|
? "dn" : "dn db-m db-l db-xl";
|
||||||
|
|
||||||
let title = document.title === "Home" ? "" : document.title;
|
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 (
|
return (
|
||||||
<div
|
<div
|
||||||
className={
|
className={
|
||||||
@ -28,7 +28,7 @@ export class HeaderBar extends Component {
|
|||||||
className="dib gray2 f9 inter absolute left-0"
|
className="dib gray2 f9 inter absolute left-0"
|
||||||
href="/"
|
href="/"
|
||||||
style={{ top: 14 }}>
|
style={{ top: 14 }}>
|
||||||
<IconHome />
|
<IconHome classes={spinnerClasses} />
|
||||||
<span
|
<span
|
||||||
className="ml2 white-d v-top lh-title"
|
className="ml2 white-d v-top lh-title"
|
||||||
style={{ paddingTop: 3 }}>
|
style={{ paddingTop: 3 }}>
|
||||||
@ -43,10 +43,14 @@ export class HeaderBar extends Component {
|
|||||||
}}>
|
}}>
|
||||||
{title}
|
{title}
|
||||||
</span>
|
</span>
|
||||||
{/* {spin} */}
|
<div className="absolute right-0 lh-copy" style={{ top: 9 }}>
|
||||||
<div className="absolute right-0 lh-copy" style={{ top: 12 }}>
|
<Sigil
|
||||||
<Sigil ship={"~" + window.ship} size={16} color={"#000000"} />
|
ship={"~" + window.ship}
|
||||||
<span className="mono white-d f9 ml2 v-top">{"~" + window.ship}</span>
|
size={16}
|
||||||
|
color={"#000000"}
|
||||||
|
classes="v-mid mix-blend-diff"
|
||||||
|
/>
|
||||||
|
<span className="mono white-d f9 ml2">{"~" + window.ship}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -2,10 +2,10 @@ import React, { Component } from "react";
|
|||||||
|
|
||||||
export class IconHome extends Component {
|
export class IconHome extends Component {
|
||||||
render() {
|
render() {
|
||||||
|
let classes = !!this.props.classes ? this.props.classes : "";
|
||||||
return (
|
return (
|
||||||
//TODO relocate to ~launch when OS1 is ported
|
|
||||||
<img
|
<img
|
||||||
className="invert-d"
|
className={"invert-d " + classes}
|
||||||
src="/~chat/img/Home.png"
|
src="/~chat/img/Home.png"
|
||||||
width={16}
|
width={16}
|
||||||
height={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: [],
|
group: [],
|
||||||
ships: []
|
ships: []
|
||||||
}, () => {
|
}, () => {
|
||||||
props.setSpinner(true);
|
props.api.setSpinner(true);
|
||||||
// if we want a "proper group" that can be managed from the contacts UI,
|
// if we want a "proper group" that can be managed from the contacts UI,
|
||||||
// we make a path of the form /~zod/cool-group
|
// we make a path of the form /~zod/cool-group
|
||||||
// if not, we make a path of the form /~/~zod/free-chat
|
// 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) {
|
if (!state.createGroup && state.groups.length === 0) {
|
||||||
chatPath = `/~${chatPath}`;
|
chatPath = `/~${chatPath}`;
|
||||||
}
|
}
|
||||||
props.api.chatView.create(
|
let submit = props.api.chatView.create(
|
||||||
chatPath, state.security, aud, state.allowHistory
|
chatPath, state.security, aud, state.allowHistory
|
||||||
);
|
);
|
||||||
props.history.push(`/~chat/room${chatPath}`);
|
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;
|
this.state = store.state;
|
||||||
store.setStateHandler(this.setState.bind(this));
|
store.setStateHandler(this.setState.bind(this));
|
||||||
this.setSpinner = this.setSpinner.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
setSpinner(spinner) {
|
|
||||||
this.setState({
|
|
||||||
spinner
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -95,12 +88,11 @@ export class Root extends Component {
|
|||||||
return (
|
return (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
sidebarHideOnMobile={true}
|
sidebarHideOnMobile={true}
|
||||||
spinner={this.state.spinner}
|
spinner={state.spinner}
|
||||||
sidebar={renderChannelSidebar(props)}
|
sidebar={renderChannelSidebar(props)}
|
||||||
sidebarShown={state.sidebarShown}
|
sidebarShown={state.sidebarShown}
|
||||||
>
|
>
|
||||||
<NewScreen
|
<NewScreen
|
||||||
setSpinner={this.setSpinner}
|
|
||||||
api={api}
|
api={api}
|
||||||
inbox={state.inbox || {}}
|
inbox={state.inbox || {}}
|
||||||
groups={state.groups || {}}
|
groups={state.groups || {}}
|
||||||
@ -124,6 +116,7 @@ export class Root extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
|
spinner={state.spinner}
|
||||||
sidebarHideOnMobile={true}
|
sidebarHideOnMobile={true}
|
||||||
sidebar={renderChannelSidebar(props)}
|
sidebar={renderChannelSidebar(props)}
|
||||||
sidebarShown={state.sidebarShown}
|
sidebarShown={state.sidebarShown}
|
||||||
@ -146,7 +139,7 @@ export class Root extends Component {
|
|||||||
let sig = props.match.url.includes("/~/");
|
let sig = props.match.url.includes("/~/");
|
||||||
if (sig) {
|
if (sig) {
|
||||||
station = '/~' + station;
|
station = '/~' + station;
|
||||||
}
|
}
|
||||||
let mailbox = state.inbox[station] || {
|
let mailbox = state.inbox[station] || {
|
||||||
config: {
|
config: {
|
||||||
read: 0,
|
read: 0,
|
||||||
@ -164,6 +157,7 @@ export class Root extends Component {
|
|||||||
return (
|
return (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
sidebarHideOnMobile={true}
|
sidebarHideOnMobile={true}
|
||||||
|
spinner={state.spinner}
|
||||||
popout={popout}
|
popout={popout}
|
||||||
sidebarShown={state.sidebarShown}
|
sidebarShown={state.sidebarShown}
|
||||||
sidebar={renderChannelSidebar(props)}
|
sidebar={renderChannelSidebar(props)}
|
||||||
@ -197,7 +191,7 @@ export class Root extends Component {
|
|||||||
let sig = props.match.url.includes("/~/");
|
let sig = props.match.url.includes("/~/");
|
||||||
if (sig) {
|
if (sig) {
|
||||||
station = '/~' + station;
|
station = '/~' + station;
|
||||||
}
|
}
|
||||||
|
|
||||||
let permission = state.permissions[station] || {
|
let permission = state.permissions[station] || {
|
||||||
kind: "",
|
kind: "",
|
||||||
@ -211,6 +205,7 @@ export class Root extends Component {
|
|||||||
return (
|
return (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
sidebarHideOnMobile={true}
|
sidebarHideOnMobile={true}
|
||||||
|
spinner={state.spinner}
|
||||||
sidebarShown={state.sidebarShown}
|
sidebarShown={state.sidebarShown}
|
||||||
popout={popout}
|
popout={popout}
|
||||||
sidebar={renderChannelSidebar(props)}
|
sidebar={renderChannelSidebar(props)}
|
||||||
@ -238,7 +233,7 @@ export class Root extends Component {
|
|||||||
let sig = props.match.url.includes("/~/");
|
let sig = props.match.url.includes("/~/");
|
||||||
if (sig) {
|
if (sig) {
|
||||||
station = '/~' + station;
|
station = '/~' + station;
|
||||||
}
|
}
|
||||||
let group = state.groups[station] || new Set([]);
|
let group = state.groups[station] || new Set([]);
|
||||||
|
|
||||||
let popout = props.match.url.includes("/popout/");
|
let popout = props.match.url.includes("/popout/");
|
||||||
@ -246,7 +241,7 @@ export class Root extends Component {
|
|||||||
return (
|
return (
|
||||||
<Skeleton
|
<Skeleton
|
||||||
sidebarHideOnMobile={true}
|
sidebarHideOnMobile={true}
|
||||||
spinner={this.state.spinner}
|
spinner={state.spinner}
|
||||||
popout={popout}
|
popout={popout}
|
||||||
sidebarShown={state.sidebarShown}
|
sidebarShown={state.sidebarShown}
|
||||||
sidebar={renderChannelSidebar(props)}
|
sidebar={renderChannelSidebar(props)}
|
||||||
@ -254,7 +249,6 @@ export class Root extends Component {
|
|||||||
<SettingsScreen
|
<SettingsScreen
|
||||||
{...props}
|
{...props}
|
||||||
station={station}
|
station={station}
|
||||||
setSpinner={this.setSpinner}
|
|
||||||
api={api}
|
api={api}
|
||||||
station={station}
|
station={station}
|
||||||
group={group}
|
group={group}
|
||||||
|
@ -26,7 +26,7 @@ export class SettingsScreen extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
isLoading: false
|
isLoading: false
|
||||||
}, () => {
|
}, () => {
|
||||||
props.setSpinner(false);
|
props.api.setSpinner(false);
|
||||||
props.history.push('/~chat');
|
props.history.push('/~chat');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ export class SettingsScreen extends Component {
|
|||||||
const { props, state } = this;
|
const { props, state } = this;
|
||||||
|
|
||||||
props.api.chatView.delete(props.station);
|
props.api.chatView.delete(props.station);
|
||||||
props.setSpinner(true);
|
props.api.setSpinner(true);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isLoading: true
|
isLoading: true
|
||||||
|
@ -5,6 +5,7 @@ export class LocalReducer {
|
|||||||
let data = _.get(json, 'local', false);
|
let data = _.get(json, 'local', false);
|
||||||
if (data) {
|
if (data) {
|
||||||
this.sidebarToggle(data, state);
|
this.sidebarToggle(data, state);
|
||||||
|
this.setSpinner(data, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,4 +15,11 @@ export class LocalReducer {
|
|||||||
state.sidebarShown = obj.sidebarToggle;
|
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