-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 617ccbe
Showing
26 changed files
with
1,441 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
*.lock | ||
|
||
# Dependency directories | ||
package-lock.json | ||
/node_modules | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Prod Bundle | ||
/build | ||
*.zip | ||
|
||
.vscode | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
"name": "vkmaboilerplate", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"homepage": "./", | ||
"scripts": { | ||
"start": "cross-env PORT=10888 HTTPS=true react-scripts start", | ||
"build": "cross-env GENERATE_SOURCEMAP=false react-scripts build", | ||
"predeploy": "npm run build", | ||
"deploy": "vk-miniapps-deploy" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@vkontakte/vk-miniapps-deploy": "0.0.25", | ||
"cross-env": "^5.2.1", | ||
"react-hot-loader": "^4.12.19", | ||
"react-scripts": "^2.1.8", | ||
"redux-devtools-extension": "^2.13.8" | ||
}, | ||
"dependencies": { | ||
"@vkontakte/icons": "^1.16.1", | ||
"@vkontakte/vk-bridge": "^2.4.1", | ||
"@vkontakte/vk-connect": "^1.8.7", | ||
"@vkontakte/vkjs": "^0.21.0", | ||
"@vkontakte/vkui": "^4.7.0", | ||
"babel-eslint": "^9.0.0", | ||
"chalk": "^2.4.2", | ||
"core-js": "^2.6.11", | ||
"eruda": "^2.4.1", | ||
"eruda-code": "^2.0.0", | ||
"eruda-dom": "^2.0.0", | ||
"prop-types": "^15.7.2", | ||
"react": "^16.12.0", | ||
"react-dom": "^16.12.0", | ||
"react-redux": "^7.1.3", | ||
"redux": "^4.0.5", | ||
"redux-thunk": "^2.3.0" | ||
}, | ||
"browserslist": [ | ||
">0.2%", | ||
"not dead", | ||
"not ie <= 11", | ||
"not op_mini all" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!DOCTYPE html> | ||
<html lang="ru"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no, viewport-fit=cover"> | ||
<meta name="theme-color" content="#000000"> | ||
<meta content="IE=Edge" http-equiv="X-UA-Compatible"> | ||
<title>VKMA Boilerplate by reyzitwo</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
import React from 'react'; | ||
import {connect} from 'react-redux'; | ||
import {bindActionCreators} from 'redux' | ||
import {goBack, closeModal, setStory} from "./js/store/router/actions"; | ||
import {getActivePanel} from "./js/services/_functions"; | ||
import * as VK from './js/services/VK'; | ||
|
||
import { | ||
Epic, | ||
View, | ||
Root, | ||
Tabbar, | ||
ModalRoot, | ||
TabbarItem, | ||
ConfigProvider, | ||
AdaptivityProvider, | ||
AppRoot, | ||
platform, | ||
VKCOM, | ||
Cell, | ||
SplitCol, | ||
PanelHeader, | ||
SplitLayout, | ||
Panel, | ||
Group | ||
} from "@vkontakte/vkui"; | ||
|
||
import { | ||
Icon28HomeOutline, | ||
Icon28Profile | ||
} from '@vkontakte/icons'; | ||
|
||
import HomePanelBase from './js/panels/home/base'; | ||
import HomePanelPlaceholder from './js/panels/home/placeholder'; | ||
|
||
import MorePanelBase from './js/panels/more/base'; | ||
|
||
import HomeBotsListModal from './js/components/modals/HomeBotsListModal'; | ||
import HomeBotInfoModal from './js/components/modals/HomeBotInfoModal'; | ||
|
||
class App extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
|
||
this.state = { | ||
isDesktop: false | ||
} | ||
|
||
this.lastAndroidBackAction = 0; | ||
} | ||
|
||
async componentDidMount() { | ||
const {goBack, dispatch} = this.props; | ||
|
||
dispatch(VK.initApp()); | ||
|
||
if (document.documentElement.clientWidth >= 1000) { | ||
this.setState({ isDesktop: true }) | ||
} | ||
|
||
window.onpopstate = () => { | ||
let timeNow = +new Date(); | ||
|
||
if (timeNow - this.lastAndroidBackAction > 500) { | ||
this.lastAndroidBackAction = timeNow; | ||
|
||
goBack(); | ||
} else { | ||
window.history.pushState(null, null); | ||
} | ||
}; | ||
} | ||
|
||
componentDidUpdate(prevProps, prevState, snapshot) { | ||
const {activeView, activeStory, activePanel, scrollPosition} = this.props; | ||
|
||
if ( | ||
prevProps.activeView !== activeView || | ||
prevProps.activePanel !== activePanel || | ||
prevProps.activeStory !== activeStory | ||
) { | ||
let pageScrollPosition = scrollPosition[activeStory + "_" + activeView + "_" + activePanel] || 0; | ||
|
||
window.scroll(0, pageScrollPosition); | ||
} | ||
} | ||
|
||
render() { | ||
const {goBack, setStory, closeModal, popouts, activeView, activeStory, activeModals, panelsHistory, colorScheme} = this.props; | ||
|
||
const hasHeader = platform !== VKCOM; | ||
const { isDesktop } = this.state | ||
|
||
let history = (panelsHistory[activeView] === undefined) ? [activeView] : panelsHistory[activeView]; | ||
let popout = (popouts[activeView] === undefined) ? null : popouts[activeView]; | ||
let activeModal = (activeModals[activeView] === undefined) ? null : activeModals[activeView]; | ||
|
||
const homeModals = ( | ||
<ModalRoot activeModal={activeModal}> | ||
<HomeBotsListModal | ||
id="MODAL_PAGE_BOTS_LIST" | ||
onClose={() => closeModal()} | ||
/> | ||
<HomeBotInfoModal | ||
id="MODAL_PAGE_BOT_INFO" | ||
onClose={() => closeModal()} | ||
/> | ||
</ModalRoot> | ||
); | ||
|
||
return ( | ||
|
||
<ConfigProvider isWebView={true} scheme={colorScheme}> | ||
<AdaptivityProvider> | ||
<AppRoot> | ||
<SplitLayout | ||
header={hasHeader && <PanelHeader separator={false} />} | ||
style={{ justifyContent: "center" }} | ||
> | ||
|
||
{isDesktop && ( | ||
<SplitCol fixed width='280px' maxWidth='280px'> | ||
<Panel> | ||
{hasHeader && <PanelHeader/>} | ||
<Group> | ||
<Cell | ||
onClick={() => setStory('home', 'base')} | ||
disabled={activeStory === 'home'} | ||
before={<Icon28HomeOutline/>} | ||
style={ activeStory === 'home' ? { | ||
backgroundColor: 'var(--button_secondary_background)', | ||
borderRadius: 8 | ||
} : {}} | ||
> | ||
Главная | ||
</Cell> | ||
<Cell | ||
onClick={() => setStory('more', 'callmodal')} | ||
disabled={activeStory === 'more'} | ||
before={<Icon28Profile/>} | ||
style={ activeStory === 'more' ? { | ||
backgroundColor: 'var(--button_secondary_background)', | ||
borderRadius: 8 | ||
} : {}} | ||
> | ||
Профиль | ||
</Cell> | ||
</Group> | ||
</Panel> | ||
</SplitCol> | ||
)} | ||
|
||
<SplitCol | ||
animate={!isDesktop} | ||
spaced={isDesktop} | ||
width={isDesktop ? '560px' : '100%'} | ||
maxWidth={isDesktop ? '560px' : '100%'}> | ||
|
||
<Epic activeStory={activeStory} tabbar={ !isDesktop && <Tabbar> | ||
<TabbarItem | ||
onClick={() => setStory('home', 'base')} | ||
selected={activeStory === 'home'} | ||
text='Главная' | ||
><Icon28HomeOutline/></TabbarItem> | ||
<TabbarItem | ||
onClick={() => setStory('more', 'callmodal')} | ||
selected={activeStory === 'more'} | ||
text='Профиль' | ||
><Icon28Profile/></TabbarItem> | ||
</Tabbar> | ||
}> | ||
<Root id="home" activeView={activeView} popout={popout}> | ||
<View | ||
id="home" | ||
modal={homeModals} | ||
activePanel={getActivePanel("home")} | ||
history={history} | ||
onSwipeBack={() => goBack()} | ||
> | ||
<HomePanelBase id="base" withoutEpic={false}/> | ||
<HomePanelPlaceholder id="placeholder"/> | ||
</View> | ||
</Root> | ||
<Root id="more" activeView={activeView} popout={popout}> | ||
<View | ||
id="more" | ||
modal={homeModals} | ||
activePanel={getActivePanel("more")} | ||
history={history} | ||
onSwipeBack={() => goBack()} | ||
> | ||
<MorePanelBase id="callmodal"/> | ||
</View> | ||
</Root> | ||
</Epic> | ||
</SplitCol> | ||
</SplitLayout> | ||
</AppRoot> | ||
</AdaptivityProvider> | ||
</ConfigProvider> | ||
); | ||
} | ||
} | ||
|
||
const mapStateToProps = (state) => { | ||
return { | ||
activeView: state.router.activeView, | ||
activeStory: state.router.activeStory, | ||
panelsHistory: state.router.panelsHistory, | ||
activeModals: state.router.activeModals, | ||
popouts: state.router.popouts, | ||
scrollPosition: state.router.scrollPosition, | ||
|
||
colorScheme: state.vkui.colorScheme | ||
}; | ||
}; | ||
|
||
|
||
function mapDispatchToProps(dispatch) { | ||
return { | ||
dispatch, | ||
...bindActionCreators({setStory, goBack, closeModal}, dispatch) | ||
} | ||
} | ||
|
||
export default connect(mapStateToProps, mapDispatchToProps)(App); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
.div-center { | ||
display: table; | ||
margin: 0 auto; | ||
} | ||
|
||
.div-center img { | ||
width: 10rem; | ||
} | ||
|
||
.buttons-group { | ||
display: flex; | ||
} | ||
|
||
.buttons-group button:first-child { | ||
margin-right: 8px; | ||
} | ||
|
||
a, div, img, p, button { | ||
user-select: none; | ||
-webkit-user-select: none; | ||
-webkit-touch-callout: none; | ||
-webkit-tap-highlight-color: transparent; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import * as eruda from 'eruda'; | ||
import * as erudaCode from 'eruda-code'; | ||
import * as erudaDom from 'eruda-dom'; | ||
|
||
eruda.init(); | ||
eruda.add(erudaCode); | ||
eruda.add(erudaDom); | ||
|
||
export default eruda; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import 'core-js/es6/map'; | ||
import 'core-js/es6/set'; | ||
|
||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
|
||
import {applyMiddleware, createStore} from "redux"; | ||
import thunk from 'redux-thunk'; | ||
import {Provider} from 'react-redux'; | ||
import rootReducer from './js/store/reducers'; | ||
import {composeWithDevTools} from 'redux-devtools-extension'; | ||
|
||
import {setStory} from "./js/store/router/actions"; | ||
|
||
import '@vkontakte/vkui/dist/vkui.css'; | ||
import './css/main.css'; | ||
|
||
import App from './App'; | ||
|
||
export const store = createStore(rootReducer, composeWithDevTools( | ||
applyMiddleware(thunk), | ||
)); | ||
|
||
store.dispatch(setStory('home', 'base')); | ||
|
||
ReactDOM.render( | ||
<Provider store={store}> | ||
<App/> | ||
</Provider>, | ||
document.getElementById('root') | ||
); | ||
|
||
import('./eruda.js').then(({ default: eruda }) => {}) |
Oops, something went wrong.