feat(topbar, sharings): introduce qrcode for sharing dirs and site address

This commit is contained in:
hexxa 2022-01-01 10:41:12 +08:00 committed by Hexxa
parent 1ff7cfc141
commit e019eb7293
7 changed files with 132 additions and 19 deletions

View file

@ -22,6 +22,8 @@
color: #16a085; color: #16a085;
padding: 1rem 2rem 1rem 2rem; padding: 1rem 2rem 1rem 2rem;
-webkit-backdrop-filter: blur(9.5px); -webkit-backdrop-filter: blur(9.5px);
position: relative;
z-index: 2;
} }
.theme-default #topbar-user-info { .theme-default #topbar-user-info {
@ -40,6 +42,8 @@
color: #16a085; color: #16a085;
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
-webkit-backdrop-filter: blur(9.5px); -webkit-backdrop-filter: blur(9.5px);
position: relative;
z-index: 1;
} }
.theme-default #top-menu button { .theme-default #top-menu button {
@ -217,6 +221,26 @@
padding: 1rem; padding: 1rem;
background-color: #ecf0f1; background-color: #ecf0f1;
display: inline-block; display: inline-block;
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 5px 30px 0 rgb(31 38 135 / 10%);
backdrop-filter: blur(9.5px);
}
.theme-default .qrcode-container {
height: 3rem;
}
.theme-default .qrcode-icon {
height: 3rem;
}
.theme-default .qrcode-child-container {
position: relative;
z-index: 50;
}
.theme-default .qrcode-child {
position: absolute;
} }
.theme-default .item-cell { .theme-default .item-cell {
@ -463,11 +487,11 @@
} }
.theme-default #login-layer { .theme-default #login-layer {
z-index: 100; z-index: 200;
} }
.theme-default #settings-layer { .theme-default #settings-layer {
z-index: 1; z-index: 100;
} }
.theme-default .value { .theme-default .value {

View file

@ -9,7 +9,7 @@ import { RiArchiveDrawerFill } from "@react-icons/all-files/ri/RiArchiveDrawerFi
import { RiFile2Fill } from "@react-icons/all-files/ri/RiFile2Fill"; import { RiFile2Fill } from "@react-icons/all-files/ri/RiFile2Fill";
import { RiFileList2Fill } from "@react-icons/all-files/ri/RiFileList2Fill"; import { RiFileList2Fill } from "@react-icons/all-files/ri/RiFileList2Fill";
import { RiCheckboxFill } from "@react-icons/all-files/ri/RiCheckboxFill"; import { RiCheckboxFill } from "@react-icons/all-files/ri/RiCheckboxFill";
import { RiInformationFill } from "@react-icons/all-files/ri/RiInformationFill"; import { RiMore2Fill } from "@react-icons/all-files/ri/RiMore2Fill";
import { BiTable } from "@react-icons/all-files/bi/BiTable"; import { BiTable } from "@react-icons/all-files/bi/BiTable";
import { BiListUl } from "@react-icons/all-files/bi/BiListUl"; import { BiListUl } from "@react-icons/all-files/bi/BiListUl";
import { RiRefreshLine } from "@react-icons/all-files/ri/RiRefreshLine"; import { RiRefreshLine } from "@react-icons/all-files/ri/RiRefreshLine";
@ -499,7 +499,7 @@ export class FilesPanel extends React.Component<Props, State, {}> {
onClick={() => this.toggleDetail(item.name)} onClick={() => this.toggleDetail(item.name)}
className="float-l" className="float-l"
> >
{getIcon("RiInformationFill", "1.8rem", detailColor)} {getIcon("RiMore2Fill", "1.8rem", detailColor)}
</span> </span>
<span onClick={() => this.select(item.name)} className="float-l"> <span onClick={() => this.select(item.name)} className="float-l">
@ -605,7 +605,7 @@ export class FilesPanel extends React.Component<Props, State, {}> {
</div> </div>
) : ( ) : (
<div className={`v-mid item-op ${showOp}`}> <div className={`v-mid item-op ${showOp}`}>
<RiInformationFill <RiMore2Fill
size="1.8rem" size="1.8rem"
className={`${descIconColor} margin-r-m`} className={`${descIconColor} margin-r-m`}
onClick={() => this.toggleDetail(item.name)} onClick={() => this.toggleDetail(item.name)}
@ -626,15 +626,22 @@ export class FilesPanel extends React.Component<Props, State, {}> {
const fileTypeTitle = this.props.msg.pkg.get("item.type"); const fileTypeTitle = this.props.msg.pkg.get("item.type");
const itemSize = FileSize(item.size, { round: 0 }); const itemSize = FileSize(item.size, { round: 0 });
const compact = item.isDir const compact = item.isDir ? (
? `${pathTitle}: ${itemPath} | ${modTimeTitle}: ${item.modTime}` <span>
: `${pathTitle}: ${itemPath} | ${modTimeTitle}: ${item.modTime} | ${sizeTitle}: ${itemSize} | sha1: ${item.sha1}`; <span className="grey3-font">{`${pathTitle}: `}</span>
<span>{`${absDownloadURL} | `}</span>
<span className="grey3-font">{`${modTimeTitle}: `}</span>
<span>{item.modTime}</span>
</span>
) : (
`${pathTitle}: ${absDownloadURL} | ${modTimeTitle}: ${item.modTime} | ${sizeTitle}: ${itemSize} | sha1: ${item.sha1}`
);
const details = ( const details = (
<div> <div>
<div className="column"> <div className="column">
<div className="card"> <div className="card">
<span className="title-m black-font">{pathTitle}</span> <span className="title-m black-font">{pathTitle}</span>
<span>{itemPath}</span> <span>{absDownloadURL}</span>
</div> </div>
<div className="card"> <div className="card">
<span className="title-m black-font">{modTimeTitle}</span> <span className="title-m black-font">{modTimeTitle}</span>

View file

@ -1,10 +1,12 @@
import * as React from "react"; import * as React from "react";
import { List } from "immutable"; import { List } from "immutable";
import QRCode from "react-qr-code";
import { RiShareBoxLine } from "@react-icons/all-files/ri/RiShareBoxLine"; import { RiShareBoxLine } from "@react-icons/all-files/ri/RiShareBoxLine";
import { RiFolderSharedFill } from "@react-icons/all-files/ri/RiFolderSharedFill"; import { RiFolderSharedFill } from "@react-icons/all-files/ri/RiFolderSharedFill";
import { RiEmotionSadLine } from "@react-icons/all-files/ri/RiEmotionSadLine"; import { RiEmotionSadLine } from "@react-icons/all-files/ri/RiEmotionSadLine";
import { QRCodeIcon } from "./visual/qrcode";
import { getErrMsg } from "../common/utils"; import { getErrMsg } from "../common/utils";
import { alertMsg, confirmMsg } from "../common/env"; import { alertMsg, confirmMsg } from "../common/env";
import { updater } from "./state_updater"; import { updater } from "./state_updater";
@ -68,13 +70,26 @@ export class SharingsPanel extends React.Component<Props, State, {}> {
<div className="info">{dirPath}</div> <div className="info">{dirPath}</div>
<div className="op"> <div className="op">
<Flexbox
children={List([
<span className="margin-r-m">
<QRCodeIcon value={sharingURL} size={128} pos={false} />
</span>,
<button <button
onClick={() => { onClick={() => {
this.deleteSharing(dirPath); this.deleteSharing(dirPath);
}} }}
> >
{this.props.msg.pkg.get("browser.delete")} {this.props.msg.pkg.get("browser.delete")}
</button> </button>,
])}
childrenStyles={List([
{ flex: "0 0 auto" },
{ flex: "0 0 auto" },
])}
style={{ justifyContent: "flex-end" }}
/>
</div> </div>
</div> </div>
); );
@ -83,7 +98,7 @@ export class SharingsPanel extends React.Component<Props, State, {}> {
<div className="sharing-item" key={dirPath}> <div className="sharing-item" key={dirPath}>
{row1} {row1}
<div className="desc">{sharingURL}</div> <div className="desc">{sharingURL}</div>
<div className="hr grey0-bg"></div> <div className="hr"></div>
</div> </div>
); );

View file

@ -13,6 +13,7 @@ import { LoginProps } from "./pane_login";
import { updater } from "./state_updater"; import { updater } from "./state_updater";
import { Flexbox } from "./layout/flexbox"; import { Flexbox } from "./layout/flexbox";
import { settingsDialogCtrl } from "./layers"; import { settingsDialogCtrl } from "./layers";
import { QRCodeIcon } from "./visual/qrcode";
export interface State {} export interface State {}
export interface Props { export interface Props {
@ -90,6 +91,7 @@ export class TopBar extends React.Component<Props, State, {}> {
> >
Quickshare Quickshare
</a>, </a>,
<QRCodeIcon value={document.URL} size={128} pos={true} className="margin-l-m"/>,
<Flexbox <Flexbox
children={List([ children={List([
@ -109,7 +111,8 @@ export class TopBar extends React.Component<Props, State, {}> {
/>, />,
])} ])}
childrenStyles={List([ childrenStyles={List([
{}, { flex: "0 0 auto" },
{ flex: "0 0 auto" },
{ justifyContent: "flex-end", alignItems: "center" }, { justifyContent: "flex-end", alignItems: "center" },
])} ])}
/> />

View file

@ -17,6 +17,7 @@ import { RiFileList2Fill } from "@react-icons/all-files/ri/RiFileList2Fill";
import { RiArrowUpDownFill } from "@react-icons/all-files/ri/RiArrowUpDownFill"; import { RiArrowUpDownFill } from "@react-icons/all-files/ri/RiArrowUpDownFill";
import { BiTable } from "@react-icons/all-files/bi/BiTable"; import { BiTable } from "@react-icons/all-files/bi/BiTable";
import { BiListUl } from "@react-icons/all-files/bi/BiListUl"; import { BiListUl } from "@react-icons/all-files/bi/BiListUl";
import { RiMore2Fill } from "@react-icons/all-files/ri/RiMore2Fill";
import { colorClass } from "./colors"; import { colorClass } from "./colors";
@ -42,6 +43,7 @@ const icons = Map<string, IconType>({
RiArrowUpDownFill: RiArrowUpDownFill, RiArrowUpDownFill: RiArrowUpDownFill,
BiTable: BiTable, BiTable: BiTable,
BiListUl: BiListUl, BiListUl: BiListUl,
RiMore2Fill: RiMore2Fill,
}); });
export function getIconWithProps( export function getIconWithProps(

View file

@ -0,0 +1,62 @@
import * as React from "react";
import QRCode from "react-qr-code";
import { RiQrCodeFill } from "@react-icons/all-files/ri/RiQrCodeFill";
export interface Props {
value: string;
size: number;
pos: boolean; // true=left, right=false
className?: string;
}
export interface State {
show: boolean;
}
export class QRCodeIcon extends React.Component<Props, State, {}> {
constructor(p: Props) {
super(p);
this.state = {
show: false,
};
}
toggle = () => {
this.setState({ show: !this.state.show });
};
show = () => {
this.setState({ show: true });
};
hide = () => {
this.setState({ show: false });
};
render() {
const widthInRem = `${Math.floor(this.props.size / 10)}rem`;
const posStyle = this.props.pos
? { right: `-${widthInRem}rem` }
: { left: `-${widthInRem}rem` };
const qrcode = this.state.show ? (
<div className="qrcode-child" style={{ ...posStyle }}>
<div className="qrcode">
<QRCode value={this.props.value} size={this.props.size} />
</div>
</div>
) : null;
return (
<div className={`qrcode-container ${this.props.className}`}>
<RiQrCodeFill
className="qrcode-icon"
onMouseEnter={this.show}
onMouseLeave={this.hide}
onClick={this.toggle}
size={"2rem"}
/>
<div className="qrcode-child-container">{qrcode}</div>
</div>
);
}
}