- added new app section manual for use through gamepad with button press.

- rename old manual-file to custom, that need to use app through form.
- added custom redirect file.
- updated meta keywords.
- updated sitemaps.
- updated dependencies.
- updated var names.
- clean template in app-custom.
This commit is contained in:
Eugene Serb 2022-08-10 16:59:32 +03:00
parent 064ccc3475
commit 4a0b8cd480
14 changed files with 311 additions and 85 deletions

36
package-lock.json generated
View File

@ -4039,9 +4039,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001374",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz",
"integrity": "sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw==",
"version": "1.0.30001375",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz",
"integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==",
"dev": true,
"funding": [
{
@ -5186,9 +5186,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
"version": "1.4.212",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.212.tgz",
"integrity": "sha512-LjQUg1SpLj2GfyaPDVBUHdhmlDU1vDB4f0mJWSGkISoXQrn5/lH3ECPCuo2Bkvf6Y30wO+b69te+rZK/llZmjg==",
"version": "1.4.213",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.213.tgz",
"integrity": "sha512-+3DbGHGOCHTVB/Ms63bGqbyC1b8y7Fk86+7ltssB8NQrZtSCvZG6eooSl9U2Q0yw++fL2DpHKOdTU0NVEkFObg==",
"dev": true
},
"node_modules/emoji-regex": {
@ -9708,9 +9708,9 @@
"dev": true
},
"node_modules/sass": {
"version": "1.54.3",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.54.3.tgz",
"integrity": "sha512-fLodey5Qd41Pxp/Tk7Al97sViYwF/TazRc5t6E65O7JOk4XF8pzwIW7CvCxYVOfJFFI/1x5+elDyBIixrp+zrw==",
"version": "1.54.4",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.54.4.tgz",
"integrity": "sha512-3tmF16yvnBwtlPrNBHw/H907j8MlOX8aTBnlNX1yrKx24RKcJGPyLhFUwkoKBKesR3unP93/2z14Ll8NicwQUA==",
"dev": true,
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
@ -14973,9 +14973,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001374",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001374.tgz",
"integrity": "sha512-mWvzatRx3w+j5wx/mpFN5v5twlPrabG8NqX2c6e45LCpymdoGqNvRkRutFUqpRTXKFQFNQJasvK0YT7suW6/Hw==",
"version": "1.0.30001375",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz",
"integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==",
"dev": true
},
"case-sensitive-paths-webpack-plugin": {
@ -15802,9 +15802,9 @@
"dev": true
},
"electron-to-chromium": {
"version": "1.4.212",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.212.tgz",
"integrity": "sha512-LjQUg1SpLj2GfyaPDVBUHdhmlDU1vDB4f0mJWSGkISoXQrn5/lH3ECPCuo2Bkvf6Y30wO+b69te+rZK/llZmjg==",
"version": "1.4.213",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.213.tgz",
"integrity": "sha512-+3DbGHGOCHTVB/Ms63bGqbyC1b8y7Fk86+7ltssB8NQrZtSCvZG6eooSl9U2Q0yw++fL2DpHKOdTU0NVEkFObg==",
"dev": true
},
"emoji-regex": {
@ -19121,9 +19121,9 @@
"dev": true
},
"sass": {
"version": "1.54.3",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.54.3.tgz",
"integrity": "sha512-fLodey5Qd41Pxp/Tk7Al97sViYwF/TazRc5t6E65O7JOk4XF8pzwIW7CvCxYVOfJFFI/1x5+elDyBIixrp+zrw==",
"version": "1.54.4",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.54.4.tgz",
"integrity": "sha512-3tmF16yvnBwtlPrNBHw/H907j8MlOX8aTBnlNX1yrKx24RKcJGPyLhFUwkoKBKesR3unP93/2z14Ll8NicwQUA==",
"dev": true,
"requires": {
"chokidar": ">=3.0.0 <4.0.0",

View File

@ -16,7 +16,7 @@
<meta name="publisher-email" content="eugene.serb@gmail.com" />
<meta name="publisher-url" content="https://eugene-serb.github.io/" />
<meta name="description" content="Wavelovers. Page with information about the project and data on donations." />
<meta name="keywords" content="Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, advertise, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, реклама" />
<meta name="keywords" content="Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, advertise, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, реклама" />
<meta name="og:title" content="Wavelovers About" />
<meta name="og:description" content="Wavelovers. Page with information about the project and data on donations." />

11
public/custom.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en-us" dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Wavelovers Redirect</title>
<meta charset="UTF-8" />
<meta http-equiv="refresh" content="0; URL=https://wavelovers.ru/?custom" />
</head>
<body>
</body>
</html>

View File

@ -16,7 +16,7 @@
<meta name="publisher-email" content="eugene.serb@gmail.com" />
<meta name="publisher-url" content="https://eugene-serb.github.io/" />
<meta name="description" content="Wavelovers. Donate to the author." />
<meta name="keywords" content="Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, Donate, Support, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, задонатить, пожертвовать, помочь, поблагодарить" />
<meta name="keywords" content="Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, Donate, Support, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, задонатить, пожертвовать, помочь, поблагодарить" />
<meta name="og:title" content="Wavelovers Donate" />
<meta name="og:description" content="Wavelovers. Donate to the author." />

View File

@ -16,7 +16,7 @@
<meta name="publisher-email" content="eugene.serb@gmail.com" />
<meta name="publisher-url" content="https://eugene-serb.github.io/" />
<meta name="description" content="Wavelovers. Frequently asked questions page." />
<meta name="keywords" content="Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, FAQ, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, часто задаваемые вопросы" />
<meta name="keywords" content="Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, FAQ, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона, часто задаваемые вопросы" />
<meta name="og:title" content="Wavelovers FAQ" />
<meta name="og:description" content="Wavelovers. Frequently asked questions page." />

View File

@ -16,7 +16,7 @@
<meta name="publisher-email" content="eugene.serb@gmail.com" />
<meta name="publisher-url" content="https://eugene-serb.github.io/" />
<meta name="description" content="Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad." />
<meta name="keywords" content="Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона" />
<meta name="keywords" content="Wavelovers, Wave Lovers, Wavemaster, Wave Master, Vibration Master, Vibration, Gamepad, Gamepad Vibration, Gamepad Massager, Vibrate Gamepad, Phone Vibration, Gamepad Tester, Phone Vibration Tester, Vibration Tester, Massager, Vibrator, Satisfyer, Womanizer, Relax, геймпад, джойстик, вибратор, вибромассажер, вибро, вибромассажёр из геймпада, тестер вибрации геймпада, тестер вибрации телефона" />
<meta name="og:title" content="Wavelovers" />
<meta name="og:description" content="Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad." />

View File

@ -2,25 +2,25 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://wavelovers.ru/</loc>
<lastmod>2022-08-09</lastmod>
<lastmod>2022-08-10</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://wavelovers.ru/faq.html</loc>
<lastmod>2022-08-09</lastmod>
<lastmod>2022-08-10</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://wavelovers.ru/about.html</loc>
<lastmod>2022-08-09</lastmod>
<lastmod>2022-08-10</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://wavelovers.ru/donate.html</loc>
<lastmod>2022-08-09</lastmod>
<lastmod>2022-08-10</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>

View File

@ -2,7 +2,7 @@
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://wavelovers.ru/sitemap-internal.xml</loc>
<lastmod>2022-08-09</lastmod>
<lastmod>2022-08-10</lastmod>
</sitemap>
</sitemapindex>

View File

@ -0,0 +1,109 @@
<template>
<div class="content-item app-custom">
<fieldset class="custom-form">
<label class="custom-form__input">
<span>Start Delay (ms)</span>
<input v-model="startDelay"
type="number" placeholder="Start Delay"
min="0" max="1000" step="25" required />
</label>
<label class="custom-form__input">
<span>Duration (ms)</span>
<input v-model="duration"
type="number" placeholder="Duration"
min="0" max="1000" step="25" required />
</label>
<label class="custom-form__input">
<span>Weak Magnitude</span>
<input v-model="weakMagnitude"
type="range" required
min="0.0" max="1.0" step="0.01" />
</label>
<label class="custom-form__input">
<span>Strong Magnitude</span>
<input v-model="strongMagnitude"
type="range" required
min="0.0" max="1.0" step="0.01" />
</label>
<div class="custom-form__buttons">
<button @click="start" class="custom-form__button">Start</button>
<button @click="stop" class="custom-form__button">Stop</button>
</div>
</fieldset>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import store from '@/store/index';
import TPatternUnit from '@/models/TPatternUnit';
export default defineComponent({
name: 'AppCustom',
data: () => {
return {
startDelay: 250 as number,
duration: 250 as number,
weakMagnitude: 1 as number,
strongMagnitude: 1 as number,
};
},
methods: {
createPatternUnit: function (): TPatternUnit[] {
const patternUnit: TPatternUnit[] = [{
startDelay: this.startDelay,
duration: this.duration,
weakMagnitude: this.weakMagnitude,
strongMagnitude: this.strongMagnitude,
}];
return patternUnit as TPatternUnit[];
},
start: function (): void {
store.dispatch('startCustom', this.createPatternUnit());
},
stop: function (): void {
store.dispatch('reset');
},
},
});
</script>
<style lang="scss">
.custom-form {
display: flex;
flex-direction: column-reverse;
justify-content: space-between;
gap: 16px;
}
.custom-form__input {
display: grid;
grid-template-columns: 1fr;
align-items: center;
}
.custom-form__buttons {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 32px;
}
.custom-form__button {
width: 100%;
}
@media only screen and (min-width: 540px) {
.custom-form {
display: flex;
flex-direction: column;
gap: 32px;
}
.custom-form__input {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
</style>

View File

@ -30,17 +30,17 @@
const result: Vibrator[] = store.getters.gamepads as Vibrator[];
result.forEach((item) => {
item.interval = timestamp;
})
});
return result;
},
},
methods: {
updateTimestamp: function (): void {
updateComputed: function (): void {
this.timestamp = Date.now();
},
},
mounted() {
this.interval = setInterval(this.updateTimestamp, 1);
this.interval = setInterval(this.updateComputed, 1);
},
unmounted() {
clearInterval(this.interval);

View File

@ -1,79 +1,167 @@
<template>
<div class="content-item app-manual">
<fieldset class="manual-form">
<label class="manual-form__input">
<span>Start Delay (ms)</span>
<input v-model="startDelay"
type="number" placeholder="Start Delay"
min="0" max="1000" step="25" required />
</label>
<label class="manual-form__input">
<span>Duration (ms)</span>
<input v-model="duration"
type="number" placeholder="Duration"
min="0" max="1000" step="25" required />
</label>
<label class="manual-form__input">
<span>Weak Magnitude</span>
<input v-model="weakMagnitude"
type="range" placeholder="Weak Magnitude"
min="0.0" max="1.0" step="0.01" required />
type="range" required disabled
min="0.0" max="1.0" step="0.01" />
</label>
<label class="manual-form__input">
<span>Strong Magnitude</span>
<input v-model="strongMagnitude"
type="range" placeholder="Strong Magnitude"
min="0.0" max="1.0" step="0.01" required />
type="range" required disabled
min="0.0" max="1.0" step="0.01" />
</label>
<div class="manual-form__buttons">
<button @click="start" class="manual-form__button">Start</button>
<button @click="stop" class="manual-form__button">Stop</button>
<div class="manual-controls">
<div>
<kbd>RT</kbd>
<span> Vibrate</span>
</div>
<div>
<kbd>A</kbd>
<span> Light Mode</span>
</div>
<div>
<kbd>X</kbd>
<span> Heavy Mode</span>
</div>
<div>
<kbd>Y</kbd>
<span> Combined Mode</span>
</div>
<div>
<kbd>B</kbd>
<span> Lock</span>
</div>
</div>
</fieldset>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import store from '@/store/index';
import Vibrator from '@/models/Vibrator';
import TPatternUnit from '@/models/TPatternUnit';
export default defineComponent({
name: 'AppManual',
name: 'AppCustom',
data: () => {
return {
startDelay: 250 as number,
duration: 250 as number,
weakMagnitude: 1 as number,
strongMagnitude: 1 as number,
startDelay: 0 as number,
duration: 260 as number,
weakMagnitude: 0 as number,
strongMagnitude: 0 as number,
timestamp: 0 as number,
interval: 0 as number,
mode: 0 as number,
lock: false as boolean,
};
},
computed: {
gamepads: function (): Vibrator[] {
const timestamp: number = this.timestamp;
const result: Vibrator[] = store.getters.gamepads as Vibrator[];
result.forEach((item) => {
item.interval = timestamp;
})
return result;
},
},
methods: {
createPatternUnit: function (): TPatternUnit[] {
const patternUnit: TPatternUnit[] = [{
createPatternUnit: function (): TPatternUnit {
const patternUnit: TPatternUnit = {
startDelay: this.startDelay,
duration: this.duration,
weakMagnitude: this.weakMagnitude,
strongMagnitude: this.strongMagnitude,
}];
return patternUnit as TPatternUnit[];
};
return patternUnit as TPatternUnit;
},
start: function (): void {
store.dispatch('startCustom', this.createPatternUnit());
},
stop: function (): void {
store.dispatch('setIsActive', false);
store.dispatch('setMode', 0);
store.dispatch('reset');
},
eventLoop: function (): void {
this.updateComputed();
this.updateMode();
this.updatePattern();
this.handle();
},
updateComputed: function (): void {
this.timestamp = Date.now();
},
updateMode: function (): void {
if (this.gamepads.length > 0) {
if (this.gamepads[0].unit.buttons[1].pressed === true) {
this.lock = !this.lock;
console.log('B', this.lock);
}
if (this.lock === false) {
if (this.gamepads[0].unit.buttons[0].pressed === true) {
this.mode = 0;
console.log('A', this.mode);
}
if (this.gamepads[0].unit.buttons[2].pressed === true) {
this.mode = 1;
console.log('X', this.mode);
}
if (this.gamepads[0].unit.buttons[3].pressed === true) {
this.mode = 2;
console.log('Y', this.mode);
}
}
}
},
updatePattern: function (): void {
if (this.gamepads.length > 0) {
if (this.lock === false) {
if (this.mode === 0) {
this.weakMagnitude = this.gamepads[0].unit.buttons[7].value;
this.strongMagnitude = this.gamepads[0].unit.buttons[7].value;
}
if (this.mode === 1) {
this.weakMagnitude = 0;
this.strongMagnitude = this.gamepads[0].unit.buttons[7].value;
}
if (this.mode === 2) {
this.weakMagnitude = this.gamepads[0].unit.buttons[7].value;
this.strongMagnitude = 0;
}
}
}
},
handle: function (): void {
if (this.gamepads.length > 0) {
this.gamepads.forEach((gamepad) => {
if (gamepad.unit.buttons[7].value > 0
|| this.lock === true) {
gamepad.unit.vibrationActuator.playEffect('dual-rumble', this.createPatternUnit());
} else {
this.stop();
}
});
}
},
},
mounted() {
this.interval = setInterval(this.eventLoop, 250);
},
unmounted() {
clearInterval(this.interval);
},
});
</script>
<style lang="scss">
.manual-form {
.app-manual {
display: flex;
flex-direction: column-reverse;
flex-direction: column;
justify-content: space-between;
gap: 16px;
gap: 32px;
}
.manual-form__input {
@ -82,28 +170,24 @@
align-items: center;
}
.manual-form__buttons {
.manual-controls {
display: flex;
flex-direction: row;
flex-direction: column;
justify-content: space-between;
gap: 32px;
}
.manual-form__button {
width: 100%;
align-self: center;
}
@media only screen and (min-width: 540px) {
.manual-form {
display: flex;
flex-direction: column;
gap: 32px;
}
.manual-form__input {
display: grid;
grid-template-columns: 1fr 1fr;
}
.manual-controls {
display: flex;
flex-direction: row;
align-self: stretch;
}
}
</style>

View File

@ -1,7 +1,8 @@
<template>
<div class="content-item navigation-list">
<router-link to="/manual" class="navigation-item">Manual</router-link>
<router-link to="/" class="navigation-item">Patterns</router-link>
<router-link to="/custom" class="navigation-item">Custom</router-link>
<router-link to="/manual" class="navigation-item">Manual</router-link>
<router-link to="/diagnostic" class="navigation-item">Diagnostic</router-link>
</div>
</template>

View File

@ -7,6 +7,11 @@ const routes: Array<RouteRecordRaw> = [
name: 'patterns-view',
component: PatternsView,
},
{
path: '/custom',
name: 'custom-view',
component: () => import('@/views/CustomView.vue'),
},
{
path: '/manual',
name: 'manual-view',

16
src/views/CustomView.vue Normal file
View File

@ -0,0 +1,16 @@
<template>
<AppCustom />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import AppCustom from '@/components/AppCustom.vue';
export default defineComponent({
name: 'CustomView',
components: {
AppCustom: AppCustom,
},
});
</script>