feat(topbar, sharings): introduce qrcode for sharing dirs and site address
This commit is contained in:
parent
1ff7cfc141
commit
e019eb7293
7 changed files with 132 additions and 19 deletions
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
<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>
|
||||
</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>
|
||||
);
|
||||
|
||||
|
|
|
@ -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" },
|
||||
])}
|
||||
/>
|
||||
|
|
|
@ -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(
|
||||
|
|
62
src/client/web/src/components/visual/qrcode.tsx
Normal file
62
src/client/web/src/components/visual/qrcode.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue