Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
guofei | 741a498ca4 | |
guofei | 9473427bd6 | |
guofei | d4959a2260 | |
guofei | 18f9e61435 | |
guofei | bed619d6ad | |
guofei | a5f133f055 | |
guofei | 42c3e51d04 | |
guofei | 86d150fb29 |
38
src/App.css
38
src/App.css
|
@ -15,6 +15,34 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media only screen and (orientation: landscape) {
|
||||
#abc {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
/* 竖屏 */
|
||||
@media only screen and (orientation: portrait) {
|
||||
#abc {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: blue;
|
||||
}
|
||||
}
|
||||
|
||||
.pane_mobile {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 200px;
|
||||
height: 100vh;
|
||||
background-color: #535353;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
|
@ -62,7 +90,7 @@
|
|||
}
|
||||
|
||||
.pane-btn.checked {
|
||||
border: 3px solid #00DE7A;
|
||||
border: 3px solid #00de7a;
|
||||
}
|
||||
|
||||
.pane-btn + .pane-btn {
|
||||
|
@ -94,8 +122,8 @@
|
|||
.language-select-container .language-select {
|
||||
width: 156px;
|
||||
height: 42px;
|
||||
background-color: #36383A;
|
||||
color: #EEEEEE;
|
||||
background-color: #36383a;
|
||||
color: #eeeeee;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -104,8 +132,8 @@
|
|||
.language-select-warpper {
|
||||
position: relative;
|
||||
border-radius: 5px;
|
||||
background: #36383A;
|
||||
border: 1px solid #5B5B5B;
|
||||
background: #36383a;
|
||||
border: 1px solid #5b5b5b;
|
||||
box-shadow: 0px 3px 0px 0px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
|
|
53
src/App.js
53
src/App.js
|
@ -29,6 +29,8 @@ import { withTranslation } from "react-i18next";
|
|||
import i18n from "i18next";
|
||||
import languageImg from "./images/language.png";
|
||||
import Arrow from './images/arrow.svg'
|
||||
import logoPanePng from "./images/logo-pane.png";
|
||||
|
||||
|
||||
import SvgIcon from '@mui/material/SvgIcon';
|
||||
|
||||
|
@ -40,11 +42,14 @@ function CustomIcon(props) {
|
|||
);
|
||||
}
|
||||
|
||||
const isMobile = () => {
|
||||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)
|
||||
}
|
||||
|
||||
class App extends React.Component {
|
||||
constructor(props) {
|
||||
super();
|
||||
this.state = {
|
||||
mode: "normal",
|
||||
projects: [],
|
||||
selectedProject: {},
|
||||
selectedProjectName: "",
|
||||
|
@ -61,10 +66,16 @@ class App extends React.Component {
|
|||
keepLogin: false,
|
||||
},
|
||||
language: localStorage.getItem("lang") ?? "zh",
|
||||
isMobile: isMobile(),
|
||||
};
|
||||
this.t = props.t;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', () => {
|
||||
this.setState({ isMobile: isMobile() });
|
||||
})
|
||||
|
||||
const loginInfo = getLoginInfo();
|
||||
var tenant = utils.getTenant();
|
||||
const hideLogo = queryString.parseUrl(window.location.href)?.query
|
||||
|
@ -161,12 +172,6 @@ class App extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
setMode(mode) {
|
||||
this.setState({
|
||||
mode: mode,
|
||||
});
|
||||
}
|
||||
|
||||
setLoginForm(form) {
|
||||
this.setState({
|
||||
loginForm: {
|
||||
|
@ -208,18 +213,7 @@ class App extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
var {
|
||||
mode,
|
||||
device,
|
||||
projects,
|
||||
selectedProject,
|
||||
dataUrl,
|
||||
loading,
|
||||
loginOpen,
|
||||
loginForm,
|
||||
hideLogo,
|
||||
language,
|
||||
} = this.state;
|
||||
const { device, projects, dataUrl, loading, loginOpen, loginForm, hideLogo, language, isMobile } = this.state;
|
||||
const { t } = this.props;
|
||||
|
||||
return (
|
||||
|
@ -277,9 +271,10 @@ class App extends React.Component {
|
|||
<Button onClick={() => this.login()}>{t("submit")}</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
{
|
||||
<Pane
|
||||
mode={mode}
|
||||
onModeChange={(_mode) => this.setMode(_mode)}
|
||||
isMobile={isMobile}
|
||||
projects={projects}
|
||||
device={device}
|
||||
loading={loading}
|
||||
|
@ -289,6 +284,10 @@ class App extends React.Component {
|
|||
}}
|
||||
onDeviceChange={(_device) => this.setDevice(_device)}
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
!isMobile &&
|
||||
<div className="language-select-container">
|
||||
<div className="language-select-warpper">
|
||||
<img className="language-icon" src={languageImg} style={{ width: "18px" }} alt="" />
|
||||
|
@ -315,6 +314,9 @@ class App extends React.Component {
|
|||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
|
@ -326,20 +328,13 @@ class App extends React.Component {
|
|||
backgroundRepeat: "no-repeat",
|
||||
}}
|
||||
>
|
||||
{mode === "normal" ? (
|
||||
<DeviceFrame
|
||||
isMobile={isMobile}
|
||||
htmlUrl={this.selectedProjectUrl}
|
||||
device={device}
|
||||
qrDataUrl={dataUrl}
|
||||
refreshQrCode={() => this.refreshQrCode()}
|
||||
/>
|
||||
) : (
|
||||
<SettingFrame
|
||||
setting={selectedProject?.TextObjStr}
|
||||
settingValue={this.projectSettingValue}
|
||||
generate={(value) => this.UpdateSetting(value)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
right: 24px;
|
||||
bottom: 24px;
|
||||
cursor: pointer;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.qrCode {
|
||||
|
|
|
@ -21,12 +21,18 @@ var configMap = {
|
|||
width: "666px",
|
||||
height: "321px",
|
||||
offsetv: "4px",
|
||||
imgStyle: {
|
||||
marginTop: '-5px',
|
||||
},
|
||||
},
|
||||
"android-v": {
|
||||
bkg: androidVPng,
|
||||
width: "321px",
|
||||
height: "666px",
|
||||
offsetv: "5px",
|
||||
imgStyle: {
|
||||
marginLeft: '2px',
|
||||
},
|
||||
},
|
||||
"iphone-h": {
|
||||
bkg: iphoneVPng,
|
||||
|
@ -39,35 +45,37 @@ var configMap = {
|
|||
},
|
||||
"iphone-v": {
|
||||
bkg: iphoneVPng,
|
||||
width: "322px",
|
||||
height: "693px",
|
||||
width: "325px",
|
||||
height: "690px",
|
||||
styles: {
|
||||
borderRadius: '13px'
|
||||
}
|
||||
},
|
||||
},
|
||||
"ipad-h": {
|
||||
bkg: ipadHPng,
|
||||
rotate: true,
|
||||
width: "458px",
|
||||
height: "326px",
|
||||
width: "646px",
|
||||
height: "478px",
|
||||
offsetv: "5px",
|
||||
imgStyle: {
|
||||
transform: 'rotate(-90deg) scale(1.4)',
|
||||
marginTop: '-2px',
|
||||
transform: 'translate(-50%, -50%) rotate(-90deg)',
|
||||
},
|
||||
styles: {
|
||||
transform: "translate(-50%, -50%) scale(1.42)",
|
||||
transform: "translate(-50%, -50%)",
|
||||
}
|
||||
},
|
||||
"ipad-v": {
|
||||
bkg: ipadHPng,
|
||||
width: "326px",
|
||||
height: "458px",
|
||||
width: "478px",
|
||||
height: "646px",
|
||||
offsetv: "5px",
|
||||
imgStyle: {
|
||||
transform: 'scale(1.4)',
|
||||
marginTop: '-2px',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
},
|
||||
styles: {
|
||||
transform: "translate(-50%, -50%) scale(1.42)",
|
||||
transform: "translate(-50%, -50%)",
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -77,11 +85,44 @@ function DeviceFrame(props) {
|
|||
var [cacheKey, setCacheKey] = useState(new Date().getTime());
|
||||
var [openPopup, setOpenPopup] = useState(false);
|
||||
var [absoluteUrl, setAbsoluteUrl] = useState("");
|
||||
var [isMobile, setIsMobile] = useState(props.isMobile);
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
setConfig(configMap[props.device]);
|
||||
}, [props.device, config]);
|
||||
// 将宽度和高度的值转换为数字,并增加10%
|
||||
const current = JSON.parse(JSON.stringify(configMap[props.device]))
|
||||
const w = parseFloat(current.width)
|
||||
const h = parseFloat(current.height)
|
||||
current.width = (w * 1.1) + 'px';
|
||||
current.height = (h * 1.1) + 'px';
|
||||
let bgW = (w * 1.1) + 32;
|
||||
let bgH = (h * 1.1) + 32;
|
||||
// 竖屏
|
||||
if (props.device === 'android-v') {
|
||||
bgW -= 12;
|
||||
} else if (props.device === 'android-h') {
|
||||
// 横屏
|
||||
bgH -= 12;
|
||||
}
|
||||
|
||||
// 平板
|
||||
if (props.device === 'ipad-v') {
|
||||
bgW += 28;
|
||||
bgH += 28;
|
||||
} else if (props.device === 'ipad-h') {
|
||||
// 横屏
|
||||
bgW += 28;
|
||||
bgH += 28;
|
||||
}
|
||||
|
||||
if (current.rotate) {
|
||||
current.imgStyle = Object.assign({ height: bgW, width: bgH }, current.imgStyle || {})
|
||||
} else {
|
||||
current.imgStyle = Object.assign({ width: bgW, height: bgH }, current.imgStyle || {})
|
||||
}
|
||||
setConfig(current);
|
||||
// setConfig(configMap[props.device]);
|
||||
}, [props.device]);
|
||||
|
||||
var refresh = () => setCacheKey(new Date().getTime());
|
||||
|
||||
|
@ -94,19 +135,22 @@ function DeviceFrame(props) {
|
|||
|
||||
return (
|
||||
<div className="deviceFrameContainer">
|
||||
|
||||
<img src={refreshButtonPng} alt="refresh" onClick={() => refresh()} className="refreshButton" />
|
||||
{props.qrDataUrl && (
|
||||
{props.qrDataUrl && !isMobile && (
|
||||
<div className="qrCode">
|
||||
<img src={props.qrDataUrl} alt="qr code" />
|
||||
<p style={{ margin: "0", }}>
|
||||
{t("scan")}
|
||||
<CopyToClipboard text={absoluteUrl} onCopy={() => setOpenPopup(true)}>
|
||||
<img style={{ cursor: "pointer", width: "20px", height: "20px" }} src={copyPng} alt="复制链接" />
|
||||
<img style={{ cursor: "pointer", width: "20px", height: "20px", marginLeft: '4px' }} src={copyPng} alt="复制链接" />
|
||||
</CopyToClipboard>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
<Snackbar
|
||||
open={openPopup}
|
||||
onClose={() => setOpenPopup(false)}
|
||||
|
@ -119,8 +163,20 @@ function DeviceFrame(props) {
|
|||
{t("copySuccess")}
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
|
||||
{
|
||||
|
||||
!isMobile ?
|
||||
<div>
|
||||
<img src={config.bkg} alt="background" style={{ position: "relative", zIndex: 100, transform: config.rotate ? "rotate(-90deg)" : "", pointerEvents: 'none', ...config.imgStyle }} />
|
||||
<img src={config.bkg} alt="background" style={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
zIndex: 100,
|
||||
transform: `translate(-50%, -50%) ${config.rotate ? "rotate(-90deg)" : ''}`,
|
||||
pointerEvents: 'none',
|
||||
...config.imgStyle
|
||||
}} />
|
||||
{props.htmlUrl && (
|
||||
<iframe
|
||||
id="deviceFrame"
|
||||
|
@ -140,7 +196,24 @@ function DeviceFrame(props) {
|
|||
frameBorder={"0"}
|
||||
/>
|
||||
)}
|
||||
</div> : <div>
|
||||
{
|
||||
props.htmlUrl && <iframe
|
||||
id="deviceFrame_mobile"
|
||||
allow="clipboard-read; clipboard-write *"
|
||||
title="preview"
|
||||
src={absoluteUrl + "&cacheKey=" + cacheKey}
|
||||
style={{
|
||||
position: 'fixed',
|
||||
inset: 0,
|
||||
width: '100vw',
|
||||
height: window.innerHeight,
|
||||
}}
|
||||
frameBorder={"0"}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,56 @@
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.selectPager {
|
||||
left: 25px !important;
|
||||
/* width: 319px !important; */
|
||||
}
|
||||
|
||||
.Pane.mobile {
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 60vw;
|
||||
height: 100vh;
|
||||
background-color: #535353;
|
||||
z-index: 1000;
|
||||
overflow: hidden;
|
||||
transition: width 0.2s linear;
|
||||
}
|
||||
|
||||
.flod-menu-btn-warpper {
|
||||
position: fixed;
|
||||
right: 12px;
|
||||
top: 10px;
|
||||
padding: 6px;
|
||||
border-radius: 6px;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
background-color: #535353;
|
||||
}
|
||||
|
||||
.flod-menu-btn-warpper .flod-menu-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
|
||||
.Pane.mobile.fold {
|
||||
padding: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.logo_mobile {
|
||||
position: absolute;
|
||||
width: 90%;
|
||||
bottom: 20px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.modeSelect {
|
||||
width: 100%;
|
||||
border: none;
|
||||
|
@ -38,11 +88,6 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selectPager {
|
||||
left: 25px !important;
|
||||
width: 319px !important;
|
||||
}
|
||||
|
||||
.bottomLogo {
|
||||
position: absolute;
|
||||
width: 322px;
|
||||
|
|
|
@ -15,6 +15,7 @@ import horizentalButton from "../../images/horizental-button.png";
|
|||
import verticalChecked from "../../images/vertical-button-checked.png";
|
||||
import verticalButton from "../../images/vertical-button.png";
|
||||
import modeSelectPng from "../../images/mode-select.png";
|
||||
import menuIcon from "../../images/menu.png";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import SvgIcon from '@mui/material/SvgIcon';
|
||||
|
||||
|
@ -26,7 +27,7 @@ function CustomIcon(props) {
|
|||
);
|
||||
}
|
||||
|
||||
var deviceConfigs = [
|
||||
const deviceConfigs = [
|
||||
{
|
||||
name: "iPhone",
|
||||
icon: iphonePng,
|
||||
|
@ -51,16 +52,12 @@ var deviceConfigs = [
|
|||
];
|
||||
|
||||
function Pane(props) {
|
||||
var [mode, setMode] = useState(props.mode);
|
||||
var [isMobile] = useState(props.isMobile);
|
||||
var [device, setDevice] = useState(props.device);
|
||||
var [project, setProject] = useState(props.project);
|
||||
const { t } = useTranslation();
|
||||
|
||||
var modeChange = (e) => {
|
||||
var _mode = e.target.value;
|
||||
setMode(_mode);
|
||||
props.onModeChange(e.target.value);
|
||||
};
|
||||
const [foldPanel, setFoldPanel] = useState(props.isMobile ? true : false);
|
||||
const { t } = useTranslation();
|
||||
|
||||
var deviceChange = (_device) => {
|
||||
setDevice(_device);
|
||||
|
@ -70,6 +67,7 @@ function Pane(props) {
|
|||
var projectSelect = (e) => {
|
||||
var projectName = e.target.value;
|
||||
setProject(projectName);
|
||||
setFoldPanel(true)
|
||||
props.onProjectSelect(projectName);
|
||||
};
|
||||
|
||||
|
@ -77,8 +75,26 @@ function Pane(props) {
|
|||
props.projects.length && !project && setProject(props.projects[0]);
|
||||
}, [props.projects]);
|
||||
|
||||
|
||||
return (
|
||||
<div className="Pane">
|
||||
<div className={`Pane ${isMobile ? 'mobile' : ''} ${foldPanel ? 'fold' : ''}`} style={{ height: window.innerHeight }}>
|
||||
{
|
||||
isMobile &&
|
||||
<div className="flod-menu-btn-warpper">
|
||||
<img
|
||||
onClick={() => {
|
||||
setFoldPanel(!foldPanel)
|
||||
}}
|
||||
src={menuIcon}
|
||||
alt="menu"
|
||||
className="flod-menu-btn"
|
||||
style={{
|
||||
transform: !foldPanel ? 'rotate(-90deg)' : '',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div>
|
||||
{props.loading ? (
|
||||
<CircularProgress color="inherit" />
|
||||
|
@ -98,9 +114,6 @@ function Pane(props) {
|
|||
borderRadius: '5px',
|
||||
color: "white",
|
||||
boxShadow: '0px 3px 0px 0px rgba(0, 0, 0, 0.3)',
|
||||
// '&.MuiOutlinedInput-notchedOutline': {
|
||||
// borderColor: '#757575', // 设置焦点时的边框颜色为红色
|
||||
// },
|
||||
'&.Mui-focused': {
|
||||
borderColor: '#757575',
|
||||
'&.MuiOutlinedInput-notchedOutline': {
|
||||
|
@ -124,7 +137,9 @@ function Pane(props) {
|
|||
)}
|
||||
</div>
|
||||
|
||||
<List
|
||||
|
||||
{
|
||||
!isMobile && <List
|
||||
sx={{
|
||||
paddingTop: '20px'
|
||||
}}
|
||||
|
@ -164,8 +179,10 @@ function Pane(props) {
|
|||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
}
|
||||
|
||||
{!props.hideLogo && <div className="bottomLogo"><img src={logoPanePng} alt="logo" width={"100%"} /></div>}
|
||||
{(!props.hideLogo && !isMobile) && <div className="bottomLogo"><img src={logoPanePng} alt="logo" width={"100%"} /></div>}
|
||||
{(!props.hideLogo && isMobile) && <img src={logoPanePng} className="logo_mobile" alt="logo" width={"100%"} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// var BaseUrl = "https://api.soyootech.com/";
|
||||
var BaseUrl = "api/";
|
||||
var BaseUrl = "https://api.soyootech.com/";
|
||||
|
||||
// var BaseUrl = "api/";
|
||||
export async function UserLogin(loginForm) {
|
||||
try {
|
||||
var response = await fetch(BaseUrl + "SoyooUser/previewlogin", {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Loading…
Reference in New Issue