fix: add mobile fit

topwar
guofei 2024-11-18 11:56:35 +08:00
parent d4959a2260
commit 9473427bd6
9 changed files with 280 additions and 169 deletions

View File

@ -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);
}

View File

@ -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>
);

View File

@ -15,6 +15,7 @@
right: 24px;
bottom: 24px;
cursor: pointer;
z-index: 1000;
}
.qrCode {

View File

@ -85,6 +85,7 @@ 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(() => {
@ -134,8 +135,9 @@ 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", }}>
@ -147,6 +149,8 @@ function DeviceFrame(props) {
</div>
)}
<Snackbar
open={openPopup}
onClose={() => setOpenPopup(false)}
@ -159,6 +163,10 @@ function DeviceFrame(props) {
{t("copySuccess")}
</Alert>
</Snackbar>
{
!isMobile ?
<div>
<img src={config.bkg} alt="background" style={{
position: "absolute",
@ -188,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>
);
}

View File

@ -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;

View File

@ -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>
);
}

View File

@ -1,6 +1,6 @@
var BaseUrl = "https://api.soyootech.com/";
// var BaseUrl = "https://api.soyootech.com/";
// var BaseUrl = "api/";
var BaseUrl = "api/";
export async function UserLogin(loginForm) {
try {
var response = await fetch(BaseUrl + "SoyooUser/previewlogin", {

BIN
src/images/menu.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,12 +1,12 @@
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
// app.use(
// "/api",
// createProxyMiddleware({
// target: "https://api.soyootech.com/",
// changeOrigin: true,
// pathRewrite: { "^/api": "" },
// })
// );
app.use(
"/api",
createProxyMiddleware({
target: "https://api.soyootech.com/",
changeOrigin: true,
pathRewrite: { "^/api": "" },
})
);
};