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;
padding: 1rem 2rem 1rem 2rem;
-webkit-backdrop-filter: blur(9.5px);
position: relative;
z-index: 2;
}
.theme-default #topbar-user-info {
@ -40,6 +42,8 @@
color: #16a085;
padding: 0.5rem 1rem;
-webkit-backdrop-filter: blur(9.5px);
position: relative;
z-index: 1;
}
.theme-default #top-menu button {
@ -217,6 +221,26 @@
padding: 1rem;
background-color: #ecf0f1;
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 {
@ -463,11 +487,11 @@
}
.theme-default #login-layer {
z-index: 100;
z-index: 200;
}
.theme-default #settings-layer {
z-index: 1;
z-index: 100;
}
.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 { RiFileList2Fill } from "@react-icons/all-files/ri/RiFileList2Fill";
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 { BiListUl } from "@react-icons/all-files/bi/BiListUl";
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)}
className="float-l"
>
{getIcon("RiInformationFill", "1.8rem", detailColor)}
{getIcon("RiMore2Fill", "1.8rem", detailColor)}
</span>
<span onClick={() => this.select(item.name)} className="float-l">
@ -605,7 +605,7 @@ export class FilesPanel extends React.Component<Props, State, {}> {
</div>
) : (
<div className={`v-mid item-op ${showOp}`}>
<RiInformationFill
<RiMore2Fill
size="1.8rem"
className={`${descIconColor} margin-r-m`}
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 itemSize = FileSize(item.size, { round: 0 });
const compact = item.isDir
? `${pathTitle}: ${itemPath} | ${modTimeTitle}: ${item.modTime}`
: `${pathTitle}: ${itemPath} | ${modTimeTitle}: ${item.modTime} | ${sizeTitle}: ${itemSize} | sha1: ${item.sha1}`;
const compact = item.isDir ? (
<span>
<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 = (
<div>
<div className="column">
<div className="card">
<span className="title-m black-font">{pathTitle}</span>
<span>{itemPath}</span>
<span>{absDownloadURL}</span>
</div>
<div className="card">
<span className="title-m black-font">{modTimeTitle}</span>

View file

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

View file

@ -13,6 +13,7 @@ import { LoginProps } from "./pane_login";
import { updater } from "./state_updater";
import { Flexbox } from "./layout/flexbox";
import { settingsDialogCtrl } from "./layers";
import { QRCodeIcon } from "./visual/qrcode";
export interface State {}
export interface Props {
@ -90,6 +91,7 @@ export class TopBar extends React.Component<Props, State, {}> {
>
Quickshare
</a>,
<QRCodeIcon value={document.URL} size={128} pos={true} className="margin-l-m"/>,
<Flexbox
children={List([
@ -109,7 +111,8 @@ export class TopBar extends React.Component<Props, State, {}> {
/>,
])}
childrenStyles={List([
{},
{ flex: "0 0 auto" },
{ flex: "0 0 auto" },
{ 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 { BiTable } from "@react-icons/all-files/bi/BiTable";
import { BiListUl } from "@react-icons/all-files/bi/BiListUl";
import { RiMore2Fill } from "@react-icons/all-files/ri/RiMore2Fill";
import { colorClass } from "./colors";
@ -42,6 +43,7 @@ const icons = Map<string, IconType>({
RiArrowUpDownFill: RiArrowUpDownFill,
BiTable: BiTable,
BiListUl: BiListUl,
RiMore2Fill: RiMore2Fill,
});
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>
);
}
}