Skip to content

Commit

Permalink
2
Browse files Browse the repository at this point in the history
  • Loading branch information
alekseev-pv committed Jun 20, 2019
1 parent 4e0e270 commit d62ebe7
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Logs
logs
*.log
npm-debug.log*
*.lock

# Dependency directories
package-lock.json
/node_modules

# Optional npm cache directory
.npm

# Prod Bundle
/build

.vscode
.idea
38 changes: 38 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "hello_world",
"version": "1.0.0",
"description": "",
"main": "index.js",
"homepage": "https://alekseev-pv.github.io/hello_vk/",
"scripts": {
"start": "cross-env PORT=10888 react-scripts start",
"build": "react-scripts build",
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
},
"keywords": [],
"author": "",
"license": "MIT",
"devDependencies": {
"cross-env": "^5.2.0",
"gh-pages": "^2.0.1",
"react-hot-loader": "^4.7.1",
"react-scripts": "^2.1.5"
},
"dependencies": {
"@vkontakte/icons": "^1.4.3",
"@vkontakte/vkui": "^2.21.5",
"@vkontakte/vkui-connect": "^1.1.3",
"babel-eslint": "^9.0.0",
"core-js": "^2.6.5",
"prop-types": "^15.7.2",
"react": "^16.8.3",
"react-dom": "^16.8.3"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
13 changes: 13 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<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>VK App Boilerplate</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
46 changes: 46 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import connect from '@vkontakte/vkui-connect';
import { View } from '@vkontakte/vkui';
import '@vkontakte/vkui/dist/vkui.css';

import Home from './panels/Home';
import Persik from './panels/Persik';

class App extends React.Component {
constructor(props) {
super(props);

this.state = {
activePanel: 'home',
fetchedUser: null,
};
}

componentDidMount() {
connect.subscribe((e) => {
switch (e.detail.type) {
case 'VKWebAppGetUserInfoResult':
this.setState({ fetchedUser: e.detail.data });
break;
default:
console.log(e.detail.type);
}
});
connect.send('VKWebAppGetUserInfo', {});
}

go = (e) => {
this.setState({ activePanel: e.currentTarget.dataset.to })
};

render() {
return (
<View activePanel={this.state.activePanel}>
<Home id="home" fetchedUser={this.state.fetchedUser} go={this.go} />
<Persik id="persik" go={this.go} />
</View>
);
}
}

export default App;
Binary file added src/img/persik.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'core-js/es6/map';
import 'core-js/es6/set';
import React from 'react';
import ReactDOM from 'react-dom';
import connect from '@vkontakte/vkui-connect';
import App from './App';
// import registerServiceWorker from './sw';

// Init VK App
connect.send('VKWebAppInit', {});

// Если вы хотите, чтобы ваше веб-приложение работало в оффлайне и загружалось быстрее,
// расскомментируйте строку с registerServiceWorker();
// Но не забывайте, что на данный момент у технологии есть достаточно подводных камней
// Подробнее про сервис воркеры можно почитать тут — https://vk.cc/8MHpmT
// registerServiceWorker();

ReactDOM.render(<App />, document.getElementById('root'));
41 changes: 41 additions & 0 deletions src/panels/Home.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Panel, ListItem, Button, Group, Div, Avatar, PanelHeader } from '@vkontakte/vkui';

const Home = ({ id, go, fetchedUser }) => (
<Panel id={id}>
<PanelHeader>Example</PanelHeader>
{fetchedUser &&
<Group title="User Data Fetched with VK Connect">
<ListItem
before={fetchedUser.photo_200 ? <Avatar src={fetchedUser.photo_200}/> : null}
description={fetchedUser.city && fetchedUser.city.title ? fetchedUser.city.title : ''}
>
{`${fetchedUser.first_name} ${fetchedUser.last_name}`}
</ListItem>
</Group>}

<Group title="Navigation Example">
<Div>
<Button size="xl" level="2" onClick={go} data-to="persik">
Show me the Persik, please
</Button>
</Div>
</Group>
</Panel>
);

Home.propTypes = {
id: PropTypes.string.isRequired,
go: PropTypes.func.isRequired,
fetchedUser: PropTypes.shape({
photo_200: PropTypes.string,
first_name: PropTypes.string,
last_name: PropTypes.string,
city: PropTypes.shape({
title: PropTypes.string,
}),
}),
};

export default Home;
6 changes: 6 additions & 0 deletions src/panels/Persik.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.Persik {
display: block;
width: 30%;
max-width: 240px;
margin: 20px auto;
}
29 changes: 29 additions & 0 deletions src/panels/Persik.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
import {Panel, PanelHeader, HeaderButton, platform, IOS} from '@vkontakte/vkui';
import persik from '../img/persik.png';
import './Persik.css';
import Icon28ChevronBack from '@vkontakte/icons/dist/28/chevron_back';
import Icon24Back from '@vkontakte/icons/dist/24/back';

const osname = platform();

const Persik = props => (
<Panel id={props.id}>
<PanelHeader
left={<HeaderButton onClick={props.go} data-to="home">
{osname === IOS ? <Icon28ChevronBack/> : <Icon24Back/>}
</HeaderButton>}
>
Persik
</PanelHeader>
<img className="Persik" src={persik} alt="Persik The Cat"/>
</Panel>
);

Persik.propTypes = {
id: PropTypes.string.isRequired,
go: PropTypes.func.isRequired,
};

export default Persik;
111 changes: 111 additions & 0 deletions src/sw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// In production, we register a service worker to serve assets from local cache.

// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.

// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.

function registerValidSW(swUrl) {
navigator.serviceWorker
.register(swUrl)
.then((registration) => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.');
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
}
}
};
};
})
.catch((error) => {
console.error('Error during service worker registration:', error);
});
}

function checkValidServiceWorker(swUrl) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then((response) => {
// Ensure service worker exists, and that we really are getting a JS file.
if (
response.status === 404 ||
response.headers.get('content-type').indexOf('javascript') === -1
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then((registration) => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl);
}
})
.catch(() => {
console.log('No internet connection found. App is running in offline mode.');
});
}

const isLocalhost = Boolean(window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));

export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return;
}

window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;

if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl);

// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://goo.gl/SC7cgQ'
);
});
} else {
// Is not local host. Just register service worker
registerValidSW(swUrl);
}
});
}
}

export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then((registration) => {
registration.unregister();
});
}
}

0 comments on commit d62ebe7

Please sign in to comment.