First commit
45
.gitignore
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Cordova
|
||||
cordova/platforms/
|
||||
cordova/plugins/
|
||||
cordova/www/
|
||||
|
||||
|
||||
|
||||
# Production build
|
||||
www/
|
||||
101
README.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# ALVINN
|
||||
|
||||
## Framework7 CLI Options
|
||||
|
||||
Framework7 app created with following options:
|
||||
|
||||
```
|
||||
{
|
||||
"cwd": "/home/mserver/ALVINN/ALVINN_f7",
|
||||
"type": [
|
||||
"web",
|
||||
"pwa",
|
||||
"cordova"
|
||||
],
|
||||
"name": "ALVINN",
|
||||
"pkg": "edu.midwestern.alvinn",
|
||||
"framework": "vue",
|
||||
"template": "single-view",
|
||||
"cssPreProcessor": false,
|
||||
"bundler": "vite",
|
||||
"cordova": {
|
||||
"folder": "cordova",
|
||||
"platforms": [
|
||||
"ios",
|
||||
"android"
|
||||
],
|
||||
"plugins": [
|
||||
"cordova-plugin-statusbar",
|
||||
"cordova-plugin-keyboard",
|
||||
"cordova-plugin-splashscreen"
|
||||
]
|
||||
},
|
||||
"theming": {
|
||||
"customColor": true,
|
||||
"color": "#002f65",
|
||||
"darkMode": false,
|
||||
"iconFonts": true
|
||||
},
|
||||
"customBuild": false
|
||||
}
|
||||
```
|
||||
|
||||
## Install Dependencies
|
||||
|
||||
First of all we need to install dependencies, run in terminal
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
## NPM Scripts
|
||||
|
||||
* 🔥 `start` - run development server
|
||||
* 🔧 `dev` - run development server
|
||||
* 🔧 `build` - build web app for production
|
||||
* 📱 `build-cordova` - build cordova app
|
||||
* 📱 `build-cordova-ios` - build cordova iOS app
|
||||
* 📱 `cordova-ios` - run dev build cordova iOS app
|
||||
* 📱 `build-cordova-android` - build cordova Android app
|
||||
* 📱 `cordova-android` - run dev build cordova Android app
|
||||
|
||||
## Vite
|
||||
|
||||
There is a [Vite](https://vitejs.dev) bundler setup. It compiles and bundles all "front-end" resources. You should work only with files located in `/src` folder. Vite config located in `vite.config.js`.
|
||||
|
||||
## PWA
|
||||
|
||||
This is a PWA. Don't forget to check what is inside of your `service-worker.js`. It is also recommended that you disable service worker (or enable "Update on reload") in browser dev tools during development.
|
||||
|
||||
## Cordova
|
||||
|
||||
Cordova project located in `cordova` folder. You shouldn't modify content of `cordova/www` folder. Its content will be correctly generated when you call `npm run cordova-build-prod`.
|
||||
## Assets
|
||||
|
||||
Assets (icons, splash screens) source images located in `assets-src` folder. To generate your own icons and splash screen images, you will need to replace all assets in this directory with your own images (pay attention to image size and format), and run the following command in the project directory:
|
||||
|
||||
```
|
||||
framework7 assets
|
||||
```
|
||||
|
||||
Or launch UI where you will be able to change icons and splash screens:
|
||||
|
||||
```
|
||||
framework7 assets --ui
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Documentation & Resources
|
||||
|
||||
* [Framework7 Core Documentation](https://framework7.io/docs/)
|
||||
* [Framework7 Vue Documentation](https://framework7.io/vue/)
|
||||
|
||||
|
||||
* [Framework7 Icons Reference](https://framework7.io/icons/)
|
||||
* [Community Forum](https://forum.framework7.io)
|
||||
|
||||
## Support Framework7
|
||||
|
||||
Love Framework7? Support project by donating or pledging on:
|
||||
- Patreon: https://patreon.com/framework7
|
||||
- OpenCollective: https://opencollective.com/framework7
|
||||
BIN
assets-src/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
assets-src/cordova-android-icon.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
assets-src/cordova-ios-icon.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
assets-src/cordova-splash-screen.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
assets-src/web-icon.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
45
build/build-cordova.js
Normal file
@@ -0,0 +1,45 @@
|
||||
const rollup = require('rollup');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const build = async () => {
|
||||
// rebuild JS without modules
|
||||
let entry = fs
|
||||
.readdirSync(path.resolve(__dirname, '../cordova/www/assets'))
|
||||
.filter((f) => f.includes('index-') && f.includes('.js'))[0];
|
||||
const hash = entry.split('index-')[1].split('.js')[0];
|
||||
|
||||
const bundle = await rollup.rollup({
|
||||
input: path.resolve(__dirname, '../cordova/www/assets/', entry),
|
||||
});
|
||||
await bundle.write({
|
||||
file: path.resolve(__dirname, '../cordova/www/assets/', `index-${hash}.js`),
|
||||
format: 'iife',
|
||||
name: 'MyApp',
|
||||
sourcemap: false,
|
||||
});
|
||||
|
||||
// Remove old chunk files
|
||||
fs.readdirSync(path.resolve(__dirname, '../cordova/www/assets')).forEach((f) => {
|
||||
if (f.includes('.js') && f.split('.').length > 2 && f !== `index-${hash}.js`) {
|
||||
fs.rmSync(path.resolve(__dirname, '../cordova/www/assets', f));
|
||||
}
|
||||
});
|
||||
|
||||
// fix index.html
|
||||
const indexPath = path.resolve(__dirname, '../cordova/www/index.html');
|
||||
const indexContent = fs
|
||||
.readFileSync(indexPath, 'utf8')
|
||||
.split('\n')
|
||||
.map((line) => {
|
||||
if (line.includes('<link rel="modulepreload"')) return '';
|
||||
if (line.includes('<script type="module"')) return '';
|
||||
if (line.includes('</body>'))
|
||||
return ` <script src="assets/index-${hash}.js"></script>\n</body>`;
|
||||
return line;
|
||||
})
|
||||
.join('\n');
|
||||
fs.writeFileSync(indexPath, indexContent);
|
||||
};
|
||||
|
||||
build();
|
||||
26
cordova/.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
.DS_Store
|
||||
|
||||
# Generated by package manager
|
||||
node_modules/
|
||||
|
||||
# Generated by Cordova
|
||||
/plugins/
|
||||
/platforms/
|
||||
77
cordova/config.xml
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<widget id="edu.midwestern.alvinn" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||
<name>ALVINN</name>
|
||||
<description>Sample Apache Cordova App</description>
|
||||
<author email="dev@cordova.apache.org" href="https://cordova.apache.org">
|
||||
Apache Cordova Team
|
||||
</author>
|
||||
<content src="index.html" />
|
||||
<allow-intent href="http://*/*" />
|
||||
<allow-intent href="https://*/*" />
|
||||
|
||||
<allow-navigation href="*" />
|
||||
|
||||
<platform name="android">
|
||||
<preference name="StatusBarOverlaysWebView" value="false" />
|
||||
<preference name="android-minSdkVersion" value="22" />
|
||||
<preference name="SplashMaintainAspectRatio" value="true" />
|
||||
<splash density="land-hdpi" src="res/screen/android/drawable-hdpi/screen.png" />
|
||||
<splash density="land-mdpi" src="res/screen/android/drawable-mdpi/screen.png" />
|
||||
<splash density="land-xhdpi" src="res/screen/android/drawable-xhdpi/screen.png" />
|
||||
<splash density="land-xxhdpi" src="res/screen/android/drawable-xxhdpi/screen.png" />
|
||||
<splash density="land-xxxhdpi" src="res/screen/android/drawable-xxxhdpi/screen.png" />
|
||||
<splash density="port-hdpi" src="res/screen/android/drawable-hdpi/screen.png" />
|
||||
<splash density="port-mdpi" src="res/screen/android/drawable-mdpi/screen.png" />
|
||||
<splash density="port-xhdpi" src="res/screen/android/drawable-xhdpi/screen.png" />
|
||||
<splash density="port-xxhdpi" src="res/screen/android/drawable-xxhdpi/screen.png" />
|
||||
<splash density="port-xxxhdpi" src="res/screen/android/drawable-xxxhdpi/screen.png" />
|
||||
<icon density="ldpi" src="res/icon/android/mipmap-ldpi/ic_launcher.png" />
|
||||
<icon density="mdpi" src="res/icon/android/mipmap-mdpi/ic_launcher.png" />
|
||||
<icon density="hdpi" src="res/icon/android/mipmap-hdpi/ic_launcher.png" />
|
||||
<icon density="xhdpi" src="res/icon/android/mipmap-xhdpi/ic_launcher.png" />
|
||||
<icon density="xxhdpi" src="res/icon/android/mipmap-xxhdpi/ic_launcher.png" />
|
||||
<icon density="xxxhdpi" src="res/icon/android/mipmap-xxxhdpi/ic_launcher.png" />
|
||||
</platform>
|
||||
|
||||
|
||||
<platform name="ios">
|
||||
<config-file parent="CFBundleAllowMixedLocalizations" platform="ios" target="*-Info.plist">
|
||||
<true />
|
||||
</config-file>
|
||||
<preference name="scheme" value="app" />
|
||||
<preference name="hostname" value="localhost" />
|
||||
<preference name="StatusBarOverlaysWebView" value="true" />
|
||||
<splash src="res/screen/ios/Default@2x~universal~anyany.png" />
|
||||
<icon height="180" src="res/icon/ios/icon-60x60@3x.png" width="180" />
|
||||
<icon height="60" src="res/icon/ios/icon-60x60@1x.png" width="60" />
|
||||
<icon height="120" src="res/icon/ios/icon-60x60@2x.png" width="120" />
|
||||
<icon height="76" src="res/icon/ios/icon-76x76@1x.png" width="76" />
|
||||
<icon height="152" src="res/icon/ios/icon-76x76@2x.png" width="152" />
|
||||
<icon height="228" src="res/icon/ios/icon-76x76@3x.png" width="228" />
|
||||
<icon height="40" src="res/icon/ios/icon-40x40@1x.png" width="40" />
|
||||
<icon height="80" src="res/icon/ios/icon-40x40@2x.png" width="80" />
|
||||
<icon height="87" src="res/icon/ios/icon-29x29@3x.png" width="87" />
|
||||
<icon height="57" src="res/icon/ios/icon-57x57@1x.png" width="57" />
|
||||
<icon height="114" src="res/icon/ios/icon-57x57@2x.png" width="114" />
|
||||
<icon height="72" src="res/icon/ios/icon-72x72@1x.png" width="72" />
|
||||
<icon height="144" src="res/icon/ios/icon-72x72@2x.png" width="144" />
|
||||
<icon height="167" src="res/icon/ios/icon-83.5x83.5@2x.png" width="167" />
|
||||
<icon height="29" src="res/icon/ios/icon-29x29@1x.png" width="29" />
|
||||
<icon height="58" src="res/icon/ios/icon-29x29@2x.png" width="58" />
|
||||
<icon height="50" src="res/icon/ios/icon-50x50@1x.png" width="50" />
|
||||
<icon height="100" src="res/icon/ios/icon-50x50@2x.png" width="100" />
|
||||
<icon height="167" src="res/icon/ios/icon-83.5x83.5@2x.png" width="167" />
|
||||
<icon height="1024" src="res/icon/ios/icon-512x512@2x.png" width="1024" />
|
||||
</platform>
|
||||
|
||||
|
||||
<preference name="DisallowOverscroll" value="true" />
|
||||
<preference name="BackupWebStorage" value="local" />
|
||||
<preference name="AutoHideSplashScreen" value="false" />
|
||||
<preference name="ShowSplashScreenSpinner" value="false" />
|
||||
<preference name="SplashScreenDelay" value="0" />
|
||||
<preference name="Suppresses3DTouchGesture" value="true" />
|
||||
<preference name="Allow3DTouchLinkPreview" value="false" />
|
||||
<preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />
|
||||
<preference name="AllowInlineMediaPlayback" value="true" />
|
||||
</widget>
|
||||
2307
cordova/package-lock.json
generated
Normal file
33
cordova/package.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "edu.midwestern.alvinn",
|
||||
"displayName": "ALVINN",
|
||||
"version": "1.0.0",
|
||||
"description": "A sample Apache Cordova application that responds to the deviceready event.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"ecosystem:cordova"
|
||||
],
|
||||
"author": "Apache Cordova Team",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"cordova-android": "^12.0.1",
|
||||
"cordova-ios": "^7.0.1",
|
||||
"cordova-plugin-keyboard": "^1.2.0",
|
||||
"cordova-plugin-splashscreen": "^6.0.2",
|
||||
"cordova-plugin-statusbar": "^4.0.0"
|
||||
},
|
||||
"cordova": {
|
||||
"plugins": {
|
||||
"cordova-plugin-statusbar": {},
|
||||
"cordova-plugin-keyboard": {},
|
||||
"cordova-plugin-splashscreen": {}
|
||||
},
|
||||
"platforms": [
|
||||
"ios",
|
||||
"android"
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
cordova/res/icon/android/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
cordova/res/icon/android/mipmap-ldpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 770 B |
BIN
cordova/res/icon/android/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 954 B |
BIN
cordova/res/icon/android/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
cordova/res/icon/android/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
cordova/res/icon/android/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
cordova/res/icon/android/playstore-icon.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
cordova/res/icon/ios/icon-20x20@1x.png
Normal file
|
After Width: | Height: | Size: 534 B |
BIN
cordova/res/icon/ios/icon-20x20@2x.png
Normal file
|
After Width: | Height: | Size: 828 B |
BIN
cordova/res/icon/ios/icon-20x20@3x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
cordova/res/icon/ios/icon-29x29@1x.png
Normal file
|
After Width: | Height: | Size: 696 B |
BIN
cordova/res/icon/ios/icon-29x29@2x.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
cordova/res/icon/ios/icon-29x29@3x.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
cordova/res/icon/ios/icon-40x40@1x.png
Normal file
|
After Width: | Height: | Size: 828 B |
BIN
cordova/res/icon/ios/icon-40x40@2x.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
cordova/res/icon/ios/icon-40x40@3x.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
cordova/res/icon/ios/icon-50x50@1x.png
Normal file
|
After Width: | Height: | Size: 977 B |
BIN
cordova/res/icon/ios/icon-50x50@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
cordova/res/icon/ios/icon-512x512@1x.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
cordova/res/icon/ios/icon-512x512@2x.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
cordova/res/icon/ios/icon-57x57@1x.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
cordova/res/icon/ios/icon-57x57@2x.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
cordova/res/icon/ios/icon-60x60@1x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
cordova/res/icon/ios/icon-60x60@2x.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
cordova/res/icon/ios/icon-60x60@3x.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
cordova/res/icon/ios/icon-72x72@1x.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
cordova/res/icon/ios/icon-72x72@2x.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
cordova/res/icon/ios/icon-76x76@1x.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
cordova/res/icon/ios/icon-76x76@2x.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
cordova/res/icon/ios/icon-76x76@3x.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
cordova/res/icon/ios/icon-83.5x83.5@2x.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
cordova/res/screen/android/drawable-hdpi/screen.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
cordova/res/screen/android/drawable-ldpi/screen.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
cordova/res/screen/android/drawable-mdpi/screen.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
cordova/res/screen/android/drawable-xhdpi/screen.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
cordova/res/screen/android/drawable-xxhdpi/screen.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
cordova/res/screen/android/drawable-xxxhdpi/screen.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
cordova/res/screen/ios/Default@2x~universal~anyany.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
33
framework7.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"cwd": "/home/mserver/ALVINN/ALVINN_f7",
|
||||
"type": [
|
||||
"web",
|
||||
"pwa",
|
||||
"cordova"
|
||||
],
|
||||
"name": "ALVINN",
|
||||
"pkg": "edu.midwestern.alvinn",
|
||||
"framework": "vue",
|
||||
"template": "single-view",
|
||||
"cssPreProcessor": false,
|
||||
"bundler": "vite",
|
||||
"cordova": {
|
||||
"folder": "cordova",
|
||||
"platforms": [
|
||||
"ios",
|
||||
"android"
|
||||
],
|
||||
"plugins": [
|
||||
"cordova-plugin-statusbar",
|
||||
"cordova-plugin-keyboard",
|
||||
"cordova-plugin-splashscreen"
|
||||
]
|
||||
},
|
||||
"theming": {
|
||||
"customColor": true,
|
||||
"color": "#002f65",
|
||||
"darkMode": false,
|
||||
"iconFonts": true
|
||||
},
|
||||
"customBuild": false
|
||||
}
|
||||
15862
package-lock.json
generated
Normal file
46
package.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "alvinn",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"description": "ALVINN",
|
||||
"repository": "",
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
"start": "npm run dev",
|
||||
"dev": "cross-env NODE_ENV=development vite",
|
||||
"build": "cross-env NODE_ENV=production vite build && npx workbox generateSW workbox-config.js",
|
||||
"build-cordova": "cross-env TARGET=cordova cross-env NODE_ENV=production vite build && node ./build/build-cordova.js && cd cordova && cordova build",
|
||||
"build-cordova-ios": "cross-env TARGET=cordova cross-env NODE_ENV=production vite build && node ./build/build-cordova.js && cd cordova && cordova build ios",
|
||||
"cordova-ios": "cross-env TARGET=cordova cross-env NODE_ENV=production vite build && node ./build/build-cordova.js && cd cordova && cordova run ios",
|
||||
"build-cordova-android": "cross-env TARGET=cordova cross-env NODE_ENV=production vite build && node ./build/build-cordova.js && cd cordova && cordova build android",
|
||||
"cordova-android": "cross-env TARGET=cordova cross-env NODE_ENV=production vite build && node ./build/build-cordova.js && cd cordova && cordova run android",
|
||||
"postinstall": "cpy --flat ./node_modules/framework7-icons/fonts/*.* ./src/fonts/ && cpy --flat ./node_modules/material-icons/iconfont/*.* ./src/fonts/"
|
||||
},
|
||||
"browserslist": [
|
||||
"IOS >= 15",
|
||||
"Safari >= 15",
|
||||
"last 5 Chrome versions",
|
||||
"last 5 Firefox versions"
|
||||
],
|
||||
"dependencies": {
|
||||
"dom7": "^4.0.6",
|
||||
"framework7": "^8.3.0",
|
||||
"framework7-icons": "^5.0.5",
|
||||
"framework7-vue": "^8.3.0",
|
||||
"material-icons": "^1.13.12",
|
||||
"skeleton-elements": "^4.0.1",
|
||||
"swiper": "^11.0.3",
|
||||
"vue": "^3.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.4.1",
|
||||
"@vue/compiler-sfc": "^3.3.8",
|
||||
"cpy-cli": "^5.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"postcss-preset-env": "^9.3.0",
|
||||
"rollup": "^2.79.1",
|
||||
"vite": "^4.5.0",
|
||||
"vite-plugin-html": "^3.2.0",
|
||||
"workbox-cli": "^7.0.0"
|
||||
}
|
||||
}
|
||||
5
postcss.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-preset-env': {},
|
||||
},
|
||||
};
|
||||
BIN
public/icons/128x128.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
public/icons/144x144.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
public/icons/152x152.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
public/icons/192x192.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
public/icons/256x256.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
public/icons/512x512.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/icons/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
public/icons/favicon.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
146
src/components/app.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<f7-app v-bind="f7params">
|
||||
|
||||
<!-- Left panel with cover effect-->
|
||||
<f7-panel left cover dark>
|
||||
<f7-view>
|
||||
<f7-page>
|
||||
<f7-navbar title="Left Panel"></f7-navbar>
|
||||
<f7-block>Left panel content goes here</f7-block>
|
||||
</f7-page>
|
||||
</f7-view>
|
||||
</f7-panel>
|
||||
|
||||
|
||||
<!-- Right panel with reveal effect-->
|
||||
<f7-panel right reveal dark>
|
||||
<f7-view>
|
||||
<f7-page>
|
||||
<f7-navbar title="Right Panel"></f7-navbar>
|
||||
<f7-block>Right panel content goes here</f7-block>
|
||||
</f7-page>
|
||||
</f7-view>
|
||||
</f7-panel>
|
||||
|
||||
|
||||
<!-- Your main view, should have "view-main" class -->
|
||||
<f7-view main class="safe-areas" url="/"></f7-view>
|
||||
|
||||
|
||||
<!-- Popup -->
|
||||
<f7-popup id="my-popup">
|
||||
<f7-view>
|
||||
<f7-page>
|
||||
<f7-navbar title="Popup">
|
||||
<f7-nav-right>
|
||||
<f7-link popup-close>Close</f7-link>
|
||||
</f7-nav-right>
|
||||
</f7-navbar>
|
||||
<f7-block>
|
||||
<p>Popup content goes here.</p>
|
||||
</f7-block>
|
||||
</f7-page>
|
||||
</f7-view>
|
||||
</f7-popup>
|
||||
|
||||
<f7-login-screen id="my-login-screen">
|
||||
<f7-view>
|
||||
<f7-page login-screen>
|
||||
<f7-login-screen-title>Login</f7-login-screen-title>
|
||||
<f7-list form>
|
||||
<f7-list-input
|
||||
type="text"
|
||||
name="username"
|
||||
placeholder="Your username"
|
||||
v-model:value="username"
|
||||
></f7-list-input>
|
||||
<f7-list-input
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder="Your password"
|
||||
v-model:value="password"
|
||||
></f7-list-input>
|
||||
</f7-list>
|
||||
<f7-list>
|
||||
<f7-list-button title="Sign In" @click="alertLoginData"></f7-list-button>
|
||||
<f7-block-footer>
|
||||
Some text about login information.<br>Click "Sign In" to close Login Screen
|
||||
</f7-block-footer>
|
||||
</f7-list>
|
||||
</f7-page>
|
||||
</f7-view>
|
||||
</f7-login-screen>
|
||||
</f7-app>
|
||||
</template>
|
||||
<script>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { f7, f7ready } from 'framework7-vue';
|
||||
import { getDevice } from 'framework7/lite-bundle';
|
||||
import cordovaApp from '../js/cordova-app.js';
|
||||
|
||||
import routes from '../js/routes.js';
|
||||
import store from '../js/store';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const device = getDevice();
|
||||
// Framework7 Parameters
|
||||
const f7params = {
|
||||
name: 'ALVINN', // App name
|
||||
theme: 'auto', // Automatic theme detection
|
||||
colors: {
|
||||
primary: '#002f65',
|
||||
},
|
||||
|
||||
|
||||
|
||||
// App store
|
||||
store: store,
|
||||
// App routes
|
||||
routes: routes,
|
||||
|
||||
// Register service worker (only on production build)
|
||||
serviceWorker: process.env.NODE_ENV ==='production' ? {
|
||||
path: '/service-worker.js',
|
||||
} : {},
|
||||
|
||||
// Input settings
|
||||
input: {
|
||||
scrollIntoViewOnFocus: device.cordova,
|
||||
scrollIntoViewCentered: device.cordova,
|
||||
},
|
||||
// Cordova Statusbar settings
|
||||
statusbar: {
|
||||
iosOverlaysWebView: true,
|
||||
androidOverlaysWebView: false,
|
||||
},
|
||||
};
|
||||
// Login screen data
|
||||
const username = ref('');
|
||||
const password = ref('');
|
||||
|
||||
const alertLoginData = () => {
|
||||
f7.dialog.alert('Username: ' + username.value + '<br>Password: ' + password.value, () => {
|
||||
f7.loginScreen.close();
|
||||
});
|
||||
}
|
||||
onMounted(() => {
|
||||
f7ready(() => {
|
||||
// Init cordova APIs (see cordova-app.js)
|
||||
if (device.cordova) {
|
||||
cordovaApp.init(f7);
|
||||
}
|
||||
|
||||
// Call F7 APIs here
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
f7params,
|
||||
username,
|
||||
password,
|
||||
alertLoginData
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
6
src/css/app.css
Normal file
@@ -0,0 +1,6 @@
|
||||
/* iOS Cordova Tweak */
|
||||
.device-cordova.device-ios {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
/* Your app custom styles here */
|
||||
56
src/css/icons.css
Normal file
@@ -0,0 +1,56 @@
|
||||
/* Material Icons Font (for MD theme) */
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Material Icons'), local('MaterialIcons-Regular'),
|
||||
url(../fonts/material-icons.woff2) format('woff2'),
|
||||
url(../fonts/material-icons.woff) format('woff');
|
||||
}
|
||||
.material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-feature-settings: 'liga';
|
||||
}
|
||||
|
||||
/* Framework7 Icons Font (for iOS theme) */
|
||||
@font-face {
|
||||
font-family: 'Framework7 Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('../fonts/Framework7Icons-Regular.woff2') format('woff2'),
|
||||
url('../fonts/Framework7Icons-Regular.woff') format('woff');
|
||||
}
|
||||
.f7-icons {
|
||||
font-family: 'Framework7 Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 28px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-feature-settings: 'liga';
|
||||
-moz-font-feature-settings: 'liga=1';
|
||||
-moz-font-feature-settings: 'liga';
|
||||
font-feature-settings: 'liga';
|
||||
text-align: center;
|
||||
}
|
||||
BIN
src/fonts/Framework7Icons-Regular.ttf
Normal file
BIN
src/fonts/Framework7Icons-Regular.woff
Normal file
BIN
src/fonts/Framework7Icons-Regular.woff2
Normal file
55
src/fonts/_mixins.scss
Normal file
@@ -0,0 +1,55 @@
|
||||
// @see https://github.com/twbs/bootstrap/blob/main/scss/_functions.scss
|
||||
@function material-icons-str-replace($string, $search, $replace: '') {
|
||||
$index: str-index($string, $search);
|
||||
@if $index {
|
||||
@return str-slice($string, 1, $index - 1) + $replace +
|
||||
material-icons-str-replace(
|
||||
str-slice($string, $index + str-length($search)),
|
||||
$search,
|
||||
$replace
|
||||
);
|
||||
}
|
||||
@return $string;
|
||||
}
|
||||
|
||||
@mixin material-icons-font-class($font-family) {
|
||||
font-family: $font-family;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: $material-icons-font-size;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased; // Support for all WebKit browsers
|
||||
-moz-osx-font-smoothing: grayscale; // Support for Firefox
|
||||
text-rendering: optimizeLegibility; // Support for Safari and Chrome
|
||||
font-feature-settings: 'liga'; // Support for IE
|
||||
}
|
||||
|
||||
@mixin material-icons-font($font-family) {
|
||||
$class-name: to-lower-case($font-family);
|
||||
$class-name: material-icons-str-replace($class-name, ' ', '-');
|
||||
$font-file: $material-icons-font-path + $class-name;
|
||||
|
||||
@font-face {
|
||||
font-family: $font-family;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: $material-icons-font-display;
|
||||
src: url('#{$font-file}.woff2') format('woff2'),
|
||||
url('#{$font-file}.woff') format('woff');
|
||||
}
|
||||
|
||||
.#{$class-name} {
|
||||
@include material-icons-font-class($font-family);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin material-icons() {
|
||||
@warn "material-icons() Sass mixin has been deprecated as of 1.0. Use '@extend .material-icons;' instead of '@include material-icons();'.";
|
||||
@include material-icons-font-class('Material Icons');
|
||||
}
|
||||
3
src/fonts/_variables.scss
Normal file
@@ -0,0 +1,3 @@
|
||||
$material-icons-font-path: './' !default;
|
||||
$material-icons-font-size: 24px !default;
|
||||
$material-icons-font-display: block !default;
|
||||
24
src/fonts/filled.css
Normal file
@@ -0,0 +1,24 @@
|
||||
@font-face {
|
||||
font-family: "Material Icons";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons.woff2") format("woff2"), url("./material-icons.woff") format("woff");
|
||||
}
|
||||
.material-icons {
|
||||
font-family: "Material Icons";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
4
src/fonts/filled.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
|
||||
@include material-icons-font('Material Icons');
|
||||
BIN
src/fonts/material-icons-outlined.woff
Normal file
BIN
src/fonts/material-icons-outlined.woff2
Normal file
BIN
src/fonts/material-icons-round.woff
Normal file
BIN
src/fonts/material-icons-round.woff2
Normal file
BIN
src/fonts/material-icons-sharp.woff
Normal file
BIN
src/fonts/material-icons-sharp.woff2
Normal file
BIN
src/fonts/material-icons-two-tone.woff
Normal file
BIN
src/fonts/material-icons-two-tone.woff2
Normal file
124
src/fonts/material-icons.css
Normal file
@@ -0,0 +1,124 @@
|
||||
@font-face {
|
||||
font-family: "Material Icons";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons.woff2") format("woff2"), url("./material-icons.woff") format("woff");
|
||||
}
|
||||
.material-icons {
|
||||
font-family: "Material Icons";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Material Icons Outlined";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons-outlined.woff2") format("woff2"), url("./material-icons-outlined.woff") format("woff");
|
||||
}
|
||||
.material-icons-outlined {
|
||||
font-family: "Material Icons Outlined";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Material Icons Round";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons-round.woff2") format("woff2"), url("./material-icons-round.woff") format("woff");
|
||||
}
|
||||
.material-icons-round {
|
||||
font-family: "Material Icons Round";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Material Icons Sharp";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons-sharp.woff2") format("woff2"), url("./material-icons-sharp.woff") format("woff");
|
||||
}
|
||||
.material-icons-sharp {
|
||||
font-family: "Material Icons Sharp";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Material Icons Two Tone";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons-two-tone.woff2") format("woff2"), url("./material-icons-two-tone.woff") format("woff");
|
||||
}
|
||||
.material-icons-two-tone {
|
||||
font-family: "Material Icons Two Tone";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
5
src/fonts/material-icons.scss
Normal file
@@ -0,0 +1,5 @@
|
||||
@import 'filled';
|
||||
@import 'outlined';
|
||||
@import 'round';
|
||||
@import 'sharp';
|
||||
@import 'two-tone';
|
||||
BIN
src/fonts/material-icons.woff
Normal file
BIN
src/fonts/material-icons.woff2
Normal file
24
src/fonts/outlined.css
Normal file
@@ -0,0 +1,24 @@
|
||||
@font-face {
|
||||
font-family: "Material Icons Outlined";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons-outlined.woff2") format("woff2"), url("./material-icons-outlined.woff") format("woff");
|
||||
}
|
||||
.material-icons-outlined {
|
||||
font-family: "Material Icons Outlined";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
4
src/fonts/outlined.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
|
||||
@include material-icons-font('Material Icons Outlined');
|
||||
24
src/fonts/round.css
Normal file
@@ -0,0 +1,24 @@
|
||||
@font-face {
|
||||
font-family: "Material Icons Round";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons-round.woff2") format("woff2"), url("./material-icons-round.woff") format("woff");
|
||||
}
|
||||
.material-icons-round {
|
||||
font-family: "Material Icons Round";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
4
src/fonts/round.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
|
||||
@include material-icons-font('Material Icons Round');
|
||||
24
src/fonts/sharp.css
Normal file
@@ -0,0 +1,24 @@
|
||||
@font-face {
|
||||
font-family: "Material Icons Sharp";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons-sharp.woff2") format("woff2"), url("./material-icons-sharp.woff") format("woff");
|
||||
}
|
||||
.material-icons-sharp {
|
||||
font-family: "Material Icons Sharp";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
4
src/fonts/sharp.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
|
||||
@include material-icons-font('Material Icons Sharp');
|
||||
24
src/fonts/two-tone.css
Normal file
@@ -0,0 +1,24 @@
|
||||
@font-face {
|
||||
font-family: "Material Icons Two Tone";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("./material-icons-two-tone.woff2") format("woff2"), url("./material-icons-two-tone.woff") format("woff");
|
||||
}
|
||||
.material-icons-two-tone {
|
||||
font-family: "Material Icons Two Tone";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
4
src/fonts/two-tone.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
@import 'variables';
|
||||
@import 'mixins';
|
||||
|
||||
@include material-icons-font('Material Icons Two Tone');
|
||||
36
src/index.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!--
|
||||
Customize this policy to fit your own app's needs. For more guidance, please refer to the docs:
|
||||
https://cordova.apache.org/docs/en/latest/
|
||||
Some notes:
|
||||
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
|
||||
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
|
||||
* Enable inline JS: add 'unsafe-inline' to default-src
|
||||
-->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: content:">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover">
|
||||
|
||||
<meta name="theme-color" content="#fff">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<title>ALVINN</title>
|
||||
<% if (TARGET === 'web') { %>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<link rel="apple-touch-icon" href="icons/apple-touch-icon.png">
|
||||
<link rel="icon" href="icons/favicon.png">
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<% } %>
|
||||
<!-- built styles file will be auto injected -->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<% if (TARGET === 'cordova') { %>
|
||||
<script src="cordova.js"></script>
|
||||
<% } %>
|
||||
<script type="module" src="./js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
30
src/js/app.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// Import Vue
|
||||
import { createApp } from 'vue';
|
||||
|
||||
// Import Framework7
|
||||
import Framework7 from 'framework7/lite-bundle';
|
||||
|
||||
// Import Framework7-Vue Plugin
|
||||
import Framework7Vue, { registerComponents } from 'framework7-vue/bundle';
|
||||
|
||||
// Import Framework7 Styles
|
||||
import 'framework7/css/bundle';
|
||||
|
||||
// Import Icons and App Custom Styles
|
||||
import '../css/icons.css';
|
||||
import '../css/app.css';
|
||||
|
||||
// Import App Component
|
||||
import App from '../components/app.vue';
|
||||
|
||||
// Init Framework7-Vue Plugin
|
||||
Framework7.use(Framework7Vue);
|
||||
|
||||
// Init App
|
||||
const app = createApp(App);
|
||||
|
||||
// Register Framework7 Vue components
|
||||
registerComponents(app);
|
||||
|
||||
// Mount the app
|
||||
app.mount('#app');
|
||||
161
src/js/cordova-app.js
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
var cordovaApp = {
|
||||
f7: null,
|
||||
/*
|
||||
This method hides splashscreen after 2 seconds
|
||||
*/
|
||||
handleSplashscreen: function () {
|
||||
var f7 = cordovaApp.f7;
|
||||
if (!window.navigator.splashscreen) return;
|
||||
setTimeout(() => {
|
||||
window.navigator.splashscreen.hide();
|
||||
}, 2000);
|
||||
},
|
||||
/*
|
||||
This method prevents back button tap to exit from app on android.
|
||||
In case there is an opened modal it will close that modal instead.
|
||||
In case there is a current view with navigation history, it will go back instead.
|
||||
*/
|
||||
handleAndroidBackButton: function () {
|
||||
var f7 = cordovaApp.f7;
|
||||
const $ = f7.$;
|
||||
|
||||
document.addEventListener(
|
||||
'backbutton',
|
||||
function (e) {
|
||||
if ($('.actions-modal.modal-in').length) {
|
||||
f7.actions.close('.actions-modal.modal-in');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
if ($('.dialog.modal-in').length) {
|
||||
f7.dialog.close('.dialog.modal-in');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
if ($('.sheet-modal.modal-in').length) {
|
||||
f7.sheet.close('.sheet-modal.modal-in');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
if ($('.popover.modal-in').length) {
|
||||
f7.popover.close('.popover.modal-in');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
if ($('.popup.modal-in').length) {
|
||||
if ($('.popup.modal-in>.view').length) {
|
||||
const currentView = f7.views.get('.popup.modal-in>.view');
|
||||
if (currentView && currentView.router && currentView.router.history.length > 1) {
|
||||
currentView.router.back();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
f7.popup.close('.popup.modal-in');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
if ($('.login-screen.modal-in').length) {
|
||||
f7.loginScreen.close('.login-screen.modal-in');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($('.page-current .searchbar-enabled').length) {
|
||||
f7.searchbar.disable('.page-current .searchbar-enabled');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($('.page-current .card-expandable.card-opened').length) {
|
||||
f7.card.close('.page-current .card-expandable.card-opened');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
const currentView = f7.views.current;
|
||||
if (currentView && currentView.router && currentView.router.history.length > 1) {
|
||||
currentView.router.back();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($('.panel.panel-in').length) {
|
||||
f7.panel.close('.panel.panel-in');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
},
|
||||
/*
|
||||
This method does the following:
|
||||
- provides cross-platform view "shrinking" on keyboard open/close
|
||||
- hides keyboard accessory bar for all inputs except where it required
|
||||
*/
|
||||
handleKeyboard: function () {
|
||||
var f7 = cordovaApp.f7;
|
||||
if (!window.Keyboard || !window.Keyboard.shrinkView) return;
|
||||
var $ = f7.$;
|
||||
window.Keyboard.shrinkView(false);
|
||||
window.Keyboard.disableScrollingInShrinkView(true);
|
||||
window.Keyboard.hideFormAccessoryBar(true);
|
||||
window.addEventListener('keyboardWillShow', () => {
|
||||
f7.input.scrollIntoView(document.activeElement, 0, true, true);
|
||||
});
|
||||
window.addEventListener('keyboardDidShow', () => {
|
||||
f7.input.scrollIntoView(document.activeElement, 0, true, true);
|
||||
});
|
||||
window.addEventListener('keyboardDidHide', () => {
|
||||
if (document.activeElement && $(document.activeElement).parents('.messagebar').length) {
|
||||
return;
|
||||
}
|
||||
window.Keyboard.hideFormAccessoryBar(false);
|
||||
});
|
||||
window.addEventListener('keyboardHeightWillChange', (event) => {
|
||||
var keyboardHeight = event.keyboardHeight;
|
||||
if (keyboardHeight > 0) {
|
||||
// Keyboard is going to be opened
|
||||
document.body.style.height = `calc(100% - ${keyboardHeight}px)`;
|
||||
$('html').addClass('device-with-keyboard');
|
||||
} else {
|
||||
// Keyboard is going to be closed
|
||||
document.body.style.height = '';
|
||||
$('html').removeClass('device-with-keyboard');
|
||||
}
|
||||
});
|
||||
$(document).on(
|
||||
'touchstart',
|
||||
'input, textarea, select',
|
||||
function (e) {
|
||||
var nodeName = e.target.nodeName.toLowerCase();
|
||||
var type = e.target.type;
|
||||
var showForTypes = ['datetime-local', 'time', 'date', 'datetime'];
|
||||
if (nodeName === 'select' || showForTypes.indexOf(type) >= 0) {
|
||||
window.Keyboard.hideFormAccessoryBar(false);
|
||||
} else {
|
||||
window.Keyboard.hideFormAccessoryBar(true);
|
||||
}
|
||||
},
|
||||
true,
|
||||
);
|
||||
},
|
||||
init: function (f7) {
|
||||
// Save f7 instance
|
||||
cordovaApp.f7 = f7;
|
||||
|
||||
document.addEventListener('deviceready', () => {
|
||||
// Handle Android back button
|
||||
cordovaApp.handleAndroidBackButton();
|
||||
|
||||
// Handle Splash Screen
|
||||
cordovaApp.handleSplashscreen();
|
||||
|
||||
// Handle Keyboard
|
||||
cordovaApp.handleKeyboard();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default cordovaApp;
|
||||
83
src/js/routes.js
Normal file
@@ -0,0 +1,83 @@
|
||||
|
||||
import HomePage from '../pages/home.vue';
|
||||
import AboutPage from '../pages/about.vue';
|
||||
import FormPage from '../pages/form.vue';
|
||||
|
||||
|
||||
import DynamicRoutePage from '../pages/dynamic-route.vue';
|
||||
import RequestAndLoad from '../pages/request-and-load.vue';
|
||||
import NotFoundPage from '../pages/404.vue';
|
||||
|
||||
var routes = [
|
||||
{
|
||||
path: '/',
|
||||
component: HomePage,
|
||||
},
|
||||
{
|
||||
path: '/about/',
|
||||
component: AboutPage,
|
||||
},
|
||||
{
|
||||
path: '/form/',
|
||||
component: FormPage,
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: '/dynamic-route/blog/:blogId/post/:postId/',
|
||||
component: DynamicRoutePage,
|
||||
},
|
||||
{
|
||||
path: '/request-and-load/user/:userId/',
|
||||
async: function ({ router, to, resolve }) {
|
||||
// App instance
|
||||
var app = router.app;
|
||||
|
||||
// Show Preloader
|
||||
app.preloader.show();
|
||||
|
||||
// User ID from request
|
||||
var userId = to.params.userId;
|
||||
|
||||
// Simulate Ajax Request
|
||||
setTimeout(function () {
|
||||
// We got user data from request
|
||||
var user = {
|
||||
firstName: 'Vladimir',
|
||||
lastName: 'Kharlampidi',
|
||||
about: 'Hello, i am creator of Framework7! Hope you like it!',
|
||||
links: [
|
||||
{
|
||||
title: 'Framework7 Website',
|
||||
url: 'http://framework7.io',
|
||||
},
|
||||
{
|
||||
title: 'Framework7 Forum',
|
||||
url: 'http://forum.framework7.io',
|
||||
},
|
||||
]
|
||||
};
|
||||
// Hide Preloader
|
||||
app.preloader.hide();
|
||||
|
||||
// Resolve route to load page
|
||||
resolve(
|
||||
{
|
||||
component: RequestAndLoad,
|
||||
},
|
||||
{
|
||||
props: {
|
||||
user: user,
|
||||
}
|
||||
}
|
||||
);
|
||||
}, 1000);
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '(.*)',
|
||||
component: NotFoundPage,
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
||||
35
src/js/store.js
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
import { createStore } from 'framework7/lite';
|
||||
|
||||
const store = createStore({
|
||||
state: {
|
||||
products: [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Apple iPhone 8',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nisi tempora similique reiciendis, error nesciunt vero, blanditiis pariatur dolor, minima sed sapiente rerum, dolorem corrupti hic modi praesentium unde saepe perspiciatis.'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Apple iPhone 8 Plus',
|
||||
description: 'Velit odit autem modi saepe ratione totam minus, aperiam, labore quia provident temporibus quasi est ut aliquid blanditiis beatae suscipit odio vel! Nostrum porro sunt sint eveniet maiores, dolorem itaque!'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'Apple iPhone X',
|
||||
description: 'Expedita sequi perferendis quod illum pariatur aliquam, alias laboriosam! Vero blanditiis placeat, mollitia necessitatibus reprehenderit. Labore dolores amet quos, accusamus earum asperiores officiis assumenda optio architecto quia neque, quae eum.'
|
||||
},
|
||||
]
|
||||
},
|
||||
getters: {
|
||||
products({ state }) {
|
||||
return state.products;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
addProduct({ state }, product) {
|
||||
state.products = [...state.products, product];
|
||||
},
|
||||
},
|
||||
})
|
||||
export default store;
|
||||
42
src/manifest.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "ALVINN",
|
||||
"short_name": "ALVINN",
|
||||
"description": "ALVINN",
|
||||
"lang": "en-US",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#002f65",
|
||||
"theme_color": "#002f65",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icons/128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/icons/144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/icons/152x152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/icons/192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/icons/256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/icons/512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
src/pages/404.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<f7-page>
|
||||
<f7-navbar title="Not found" back-link="Back"></f7-navbar>
|
||||
<f7-block strong inset>
|
||||
<p>Sorry</p>
|
||||
<p>Requested content not found.</p>
|
||||
</f7-block>
|
||||
</f7-page>
|
||||
</template>
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
23
src/pages/about.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<f7-page name="about">
|
||||
<f7-navbar title="About" back-link="Back"></f7-navbar>
|
||||
<f7-block-title>About My App</f7-block-title>
|
||||
<f7-block>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Magni molestiae laudantium
|
||||
dignissimos est nobis delectus nemo ea alias voluptatum architecto, amet similique, saepe
|
||||
iste consectetur in repellat ut minus quibusdam!
|
||||
</p>
|
||||
<p>
|
||||
Molestias et distinctio porro nesciunt ratione similique, magni doloribus, rerum nobis,
|
||||
aliquam quae reiciendis quasi modi. Nam a recusandae, fugiat in ea voluptates fuga eius,
|
||||
velit corrupti reprehenderit dignissimos consequatur!
|
||||
</p>
|
||||
<p>
|
||||
Blanditiis, cumque quo adipisci. Molestiae, dolores dolorum quos doloremque ipsa ullam
|
||||
eligendi commodi deserunt doloribus inventore magni? Ea mollitia veniam nostrum nihil, iusto
|
||||
doloribus a at! Ea molestiae ullam delectus!
|
||||
</p>
|
||||
</f7-block>
|
||||
</f7-page>
|
||||
</template>
|
||||