mirror of
https://github.com/Priler/jarvis.git
synced 2026-05-26 07:08:11 +00:00
frontend cleanup
This commit is contained in:
19
frontend/_src/App.svelte
Normal file
19
frontend/_src/App.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<!-- src/App.svelte -->
|
||||
<script>
|
||||
import { Router } from "@roxi/routify";
|
||||
import routes from "../.routify/routes.default.js";
|
||||
|
||||
import { SvelteUIProvider } from '@svelteuidev/core';
|
||||
|
||||
import Events from "./Events.svelte";
|
||||
|
||||
/** START LISTENING **/
|
||||
// import { startListening } from "./functions";
|
||||
// startListening();
|
||||
</script>
|
||||
|
||||
<SvelteUIProvider themeObserver='dark' withNormalizeCSS withGlobalStyles>
|
||||
<Router {routes} />
|
||||
</SvelteUIProvider>
|
||||
|
||||
<Events />
|
||||
44
frontend/_src/Events.svelte
Normal file
44
frontend/_src/Events.svelte
Normal file
@@ -0,0 +1,44 @@
|
||||
<script>
|
||||
import { onMount, onDestroy } from 'svelte'
|
||||
import { emit, listen } from '@tauri-apps/api/event'
|
||||
|
||||
import { resolveResource } from '@tauri-apps/api/path'
|
||||
|
||||
import {Howl, Howler} from 'howler';
|
||||
|
||||
let assistant_voice_val = "jarvis-og";
|
||||
import { assistant_voice } from "@/stores"
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
assistant_voice.subscribe(value => {
|
||||
assistant_voice_val = value;
|
||||
});
|
||||
|
||||
onMount(async () => {
|
||||
await listen('audio-play', async (event) => {
|
||||
// event.event is the event name (useful if you want to use a single callback fn for multiple event types)
|
||||
// event.payload is the payload object
|
||||
// let path = await resolveResource('sound/' + (assistant_voice_val == "" ? "jarvis-remake":assistant_voice_val) + '/' + event.payload['data'] + '.wav');
|
||||
// console.log(path);
|
||||
// let sound = new Howl({
|
||||
// src: [path],
|
||||
// html5: true
|
||||
// });
|
||||
|
||||
// sound.play();
|
||||
|
||||
let filename = 'sound/' + (assistant_voice_val == "" ? "jarvis-remake":assistant_voice_val) + '/' + event.payload['data'] + '.wav';
|
||||
await invoke("play_sound", {
|
||||
filename: filename,
|
||||
sleep: true
|
||||
});
|
||||
});
|
||||
|
||||
await listen('assistant-greet', (event) => {
|
||||
document.getElementById("arc-reactor")?.classList.add("active");
|
||||
});
|
||||
|
||||
await listen('assistant-waiting', (event) => {
|
||||
document.getElementById("arc-reactor")?.classList.remove("active");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
73
frontend/_src/components/Footer.svelte
Normal file
73
frontend/_src/components/Footer.svelte
Normal file
@@ -0,0 +1,73 @@
|
||||
<script>
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
|
||||
import { tg_official_link, github_repository_link } from "@/stores";
|
||||
|
||||
let current_year = new Date().getFullYear();
|
||||
let author_name = "";
|
||||
|
||||
(async () => {
|
||||
author_name = await invoke("get_author_name")
|
||||
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
</script>
|
||||
|
||||
<footer id="footer">
|
||||
<p>© {current_year}. Автор проекта: {author_name}</p>
|
||||
<p style="margin-top: 5px;margin-bottom: 15px;">
|
||||
<a href="{tg_official_link}" target="_blank" class="special-link"><img src="/media/icons/howdy-logo.png" alt="" width="20px"> Наш телеграм</a> канал.
|
||||
|
||||
<a href="{github_repository_link}" target="_blank"><img src="/media/icons/github-logo.png" alt="" width="18px"> Github репозиторий</a> проекта.</p>
|
||||
</footer>
|
||||
|
||||
<style lang="scss">
|
||||
#footer {
|
||||
text-align: center;
|
||||
color: #565759;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 1.7em;
|
||||
margin-top: 15px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #185876;
|
||||
text-decoration: none;
|
||||
transition: opacity .5s;
|
||||
|
||||
img {
|
||||
opacity: .5;
|
||||
transition: opacity .5s;
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #2A9CD0;
|
||||
|
||||
img {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.special-link {
|
||||
color: #941d92;
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
color: #FF07FC;
|
||||
|
||||
background: url(/media/images/bg/bg24.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
28
frontend/_src/components/Header.svelte
Normal file
28
frontend/_src/components/Header.svelte
Normal file
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { Dashboard, Gear } from 'radix-icons-svelte'
|
||||
import {isActive} from '@roxi/routify'
|
||||
|
||||
let app_version = "";
|
||||
|
||||
(async () => {
|
||||
app_version = await invoke("get_app_version")
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
</script>
|
||||
<header id="header">
|
||||
<div class="logo">
|
||||
<a href="/" title="Проект канала Хауди Хо!"><img src="/media/header-logo.png" alt=""></a>
|
||||
<div>
|
||||
<h1><a href="/">JARVIS</a></h1>
|
||||
<h2>v{app_version} <small style="color: #8AC832;opacity: .9;font-size: 13px;">BETA</small></h2>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="top-menu">
|
||||
<ul>
|
||||
<li><a href="/commands" class:active={$isActive('/commands')}><Dashboard /> Команды</a></li>
|
||||
<li><a href="/settings" class:active={$isActive('/settings')}><Gear /> Настройки</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
5
frontend/_src/components/Nav.svelte
Normal file
5
frontend/_src/components/Nav.svelte
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
<nav>
|
||||
<a href="/index">Main Page</a>
|
||||
<a href="/settings">Настройки</a>
|
||||
</nav>
|
||||
647
frontend/_src/components/elements/ArcReactor.svelte
Normal file
647
frontend/_src/components/elements/ArcReactor.svelte
Normal file
@@ -0,0 +1,647 @@
|
||||
<!-- Based on: https://github.com/rembertdesigns/Iron-Man-Arc-Reactor-Pure-CSS and https://codepen.io/FlyingEmu/pen/DZNqEj -->
|
||||
<div id="arc-reactor" class="reactor-container">
|
||||
<div class="reactor-container-inner circle abs-center">
|
||||
<ul class="marks"><li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li></ul>
|
||||
<div class="e7">
|
||||
<div class="semi_arc_3 e5_1">
|
||||
<div class="semi_arc_3 e5_2">
|
||||
<div class="semi_arc_3 e5_3">
|
||||
<div class="semi_arc_3 e5_4" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tunnel circle abs-center" />
|
||||
<div class="core-wrapper circle abs-center" />
|
||||
<div class="core-outer circle abs-center" />
|
||||
<div class="core-inner circle abs-center" />
|
||||
<div class="coil-container">
|
||||
<div class="coil coil-1" />
|
||||
<div class="coil coil-2" />
|
||||
<div class="coil coil-3" />
|
||||
<div class="coil coil-4" />
|
||||
<div class="coil coil-5" />
|
||||
<div class="coil coil-6" />
|
||||
<div class="coil coil-7" />
|
||||
<div class="coil coil-8" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss" global>
|
||||
$arc_radius: 130px;
|
||||
$size3: 6px;
|
||||
$cshadow: rgba(2, 254, 255, 0.8);
|
||||
$marks_color_1: rgba(2, 254, 255, 1);
|
||||
$marks_color_2: rgba(2, 254, 255, 0.3);
|
||||
$colour1: rgba(2, 255, 255, 0.15);
|
||||
$colour3: rgba(2, 255, 255, 0.3);
|
||||
$cshadow: rgba(2, 254, 255, 0.8);
|
||||
|
||||
.reactor-container {
|
||||
width: 300px;
|
||||
height: 320px;
|
||||
margin: auto;
|
||||
// border: 1px dashed #888;
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
transition: scale 1s ease, opacity .5s ease;
|
||||
scale: 0.9;
|
||||
opacity: .9;
|
||||
// background-color: #384c50;
|
||||
// border: 1px solid #121414;
|
||||
// box-shadow: 0px 0px 32px 8px #121414, 0px 0px 4px 1px #121414 inset;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.reactor-container-inner {
|
||||
height: 238px;
|
||||
width: 238px;
|
||||
background-color: #161a1b;
|
||||
box-shadow: 0px 0px 50px 15px $colour3, inset 0px 0px 50px 15px $colour3;
|
||||
// box-shadow: 0px 0px 4px 1px #52fefe;
|
||||
}
|
||||
.circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.abs-center {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
}
|
||||
.core-inner {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border: 5px solid #1b4e5f;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 7px 5px #52fefe, 0px 0px 10px 10px #52fefe inset;
|
||||
}
|
||||
.core-outer {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border: 1px solid #52fefe;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 2px 1px #52fefe, 0px 0px 10px 5px #52fefe inset;
|
||||
}
|
||||
.core-wrapper {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
background-color: #073c4b;
|
||||
box-shadow: 0px 0px 5px 4px #52fefe, 0px 0px 6px 2px #52fefe inset;
|
||||
}
|
||||
.tunnel {
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 5px 1px #52fefe, 0px 0px 5px 4px #52fefe inset;
|
||||
}
|
||||
.coil-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: 10s infinite linear reactor-anim;
|
||||
transition: animation 1s;
|
||||
}
|
||||
.coil {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 20px;
|
||||
top: calc(50% - 110px);
|
||||
left: calc(50% - 15px);
|
||||
transform-origin: 15px 110px;
|
||||
background-color: #073c4b;
|
||||
box-shadow: 0px 0px 5px #52fefe inset;
|
||||
}
|
||||
.coil-1 {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
.coil-2 {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.coil-3 {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.coil-4 {
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
.coil-5 {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.coil-6 {
|
||||
transform: rotate(225deg);
|
||||
}
|
||||
.coil-7 {
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
.coil-8 {
|
||||
transform: rotate(315deg);
|
||||
}
|
||||
@keyframes reactor-anim {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-radius($pixel...) {
|
||||
border-radius: $pixel;
|
||||
}
|
||||
|
||||
.e7 {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 160%;
|
||||
height: 160%;
|
||||
left: -32.5%;
|
||||
top: -32.5%;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
border: $size3 solid transparent;
|
||||
background: transparent;
|
||||
@include border-radius(50%);
|
||||
transform: rotateZ(0deg);
|
||||
transition: box-shadow 3s ease;
|
||||
text-align: center;
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
.semi_arc {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 6px solid #02feff;
|
||||
background: rgba(2, 254, 255, 0.2);
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
transform: rotateZ(0deg);
|
||||
transition: box-shadow 3s ease;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.semi_arc:hover {
|
||||
box-shadow: 0px 0px 30px $cshadow;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.semi_arc_2 {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 94%;
|
||||
height: 94%;
|
||||
left: 3%;
|
||||
top: 3%;
|
||||
border: 5px solid #02feff;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
animation: rotate 4s linear infinite;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.semi_arc_2:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 94%;
|
||||
height: 94%;
|
||||
left: 3%;
|
||||
top: 3%;
|
||||
border: 4px solid #02feff;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
animation: rotate_anti 2s linear infinite;
|
||||
}
|
||||
|
||||
.semi_arc_3 {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 94%;
|
||||
height: 94%;
|
||||
left: 3%;
|
||||
top: 3%;
|
||||
border: 5px solid #02feff;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
animation: rotate 4s linear infinite;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.e1:after {
|
||||
border-color: rgba(2, 255, 255, 0.6);
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
|
||||
.e2:after {
|
||||
border-color: rgba(2, 255, 255, 0.6);
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-bottom: 5px solid transparent;
|
||||
}
|
||||
|
||||
.e3 {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
animation: rotate 5s linear infinite;
|
||||
}
|
||||
|
||||
.e3:after {
|
||||
border-color: rgba(2, 255, 255, 0.6);
|
||||
border-top: 5px solid transparent;
|
||||
border-bottom: 5px solid transparent;
|
||||
}
|
||||
|
||||
.e4 {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.e4_1 {
|
||||
border-color: rgba(2, 255, 255, 0.3);
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
|
||||
.e4_1:after {
|
||||
border-color: rgba(2, 255, 255, 0.6);
|
||||
border-top: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
}
|
||||
|
||||
.e5 {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.e5_1 {
|
||||
color: rgba(2, 255, 255, 0.15);
|
||||
border: 2px solid;
|
||||
border-left: 2px solid transparent;
|
||||
animation: rotate 5s linear infinite;
|
||||
}
|
||||
|
||||
.e5_2 {
|
||||
color: rgba(2, 255, 255, 0.7);
|
||||
border: 4px solid;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
animation: rotate_anti 4s linear infinite;
|
||||
}
|
||||
|
||||
.e5_3 {
|
||||
color: rgba(2, 255, 255, 0.5);
|
||||
border: 2px solid;
|
||||
border-left: 2px solid transparent;
|
||||
border-right: 2px solid transparent;
|
||||
animation: rotate 3s linear infinite;
|
||||
}
|
||||
|
||||
.e5_4 {
|
||||
color: rgba(2, 255, 255, 0.15);
|
||||
border: 4px solid;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
animation: rotate_anti 2s linear infinite;
|
||||
}
|
||||
|
||||
.e6 {
|
||||
border-color: transparent;
|
||||
background: rgba(255, 255, 255, 0);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
@keyframes rotate_anti {
|
||||
0% {
|
||||
transform: rotateZ(360deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.marks {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
|
||||
li {
|
||||
display: block;
|
||||
width: 3px;
|
||||
height: 11px;
|
||||
background: $cshadow;
|
||||
position: absolute;
|
||||
margin-left: 117.5px;
|
||||
margin-top: 113.5px;
|
||||
animation: colour_ease2 3s infinite ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes colour_ease2 {
|
||||
0% {
|
||||
background: $marks_color_1;
|
||||
}
|
||||
50% {
|
||||
background: $marks_color_2;
|
||||
}
|
||||
100% {
|
||||
background: $marks_color_1;
|
||||
}
|
||||
}
|
||||
|
||||
.marks li:first-child {
|
||||
transform: rotate(6deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(2) {
|
||||
transform: rotate(12deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(3) {
|
||||
transform: rotate(18deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(4) {
|
||||
transform: rotate(24deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(5) {
|
||||
transform: rotate(30deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(6) {
|
||||
transform: rotate(36deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(7) {
|
||||
transform: rotate(42deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(8) {
|
||||
transform: rotate(48deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(9) {
|
||||
transform: rotate(54deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(10) {
|
||||
transform: rotate(60deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(11) {
|
||||
transform: rotate(66deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(12) {
|
||||
transform: rotate(72deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(13) {
|
||||
transform: rotate(78deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(14) {
|
||||
transform: rotate(84deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(15) {
|
||||
transform: rotate(90deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(16) {
|
||||
transform: rotate(96deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(17) {
|
||||
transform: rotate(102deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(18) {
|
||||
transform: rotate(108deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(19) {
|
||||
transform: rotate(114deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(20) {
|
||||
transform: rotate(120deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(21) {
|
||||
transform: rotate(126deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(22) {
|
||||
transform: rotate(132deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(23) {
|
||||
transform: rotate(138deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(24) {
|
||||
transform: rotate(144deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(25) {
|
||||
transform: rotate(150deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(26) {
|
||||
transform: rotate(156deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(27) {
|
||||
transform: rotate(162deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(28) {
|
||||
transform: rotate(168deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(29) {
|
||||
transform: rotate(174deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(30) {
|
||||
transform: rotate(180deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(31) {
|
||||
transform: rotate(186deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(32) {
|
||||
transform: rotate(192deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(33) {
|
||||
transform: rotate(198deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(34) {
|
||||
transform: rotate(204deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(35) {
|
||||
transform: rotate(210deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(36) {
|
||||
transform: rotate(216deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(37) {
|
||||
transform: rotate(222deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(38) {
|
||||
transform: rotate(228deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(39) {
|
||||
transform: rotate(234deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(40) {
|
||||
transform: rotate(240deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(41) {
|
||||
transform: rotate(246deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(42) {
|
||||
transform: rotate(252deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(43) {
|
||||
transform: rotate(258deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(44) {
|
||||
transform: rotate(264deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(45) {
|
||||
transform: rotate(270deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(46) {
|
||||
transform: rotate(276deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(47) {
|
||||
transform: rotate(282deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(48) {
|
||||
transform: rotate(288deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(49) {
|
||||
transform: rotate(294deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(50) {
|
||||
transform: rotate(300deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(51) {
|
||||
transform: rotate(306deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(52) {
|
||||
transform: rotate(312deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(53) {
|
||||
transform: rotate(318deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(54) {
|
||||
transform: rotate(324deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(55) {
|
||||
transform: rotate(330deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(56) {
|
||||
transform: rotate(336deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(57) {
|
||||
transform: rotate(342deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(58) {
|
||||
transform: rotate(348deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(59) {
|
||||
transform: rotate(354deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(60) {
|
||||
transform: rotate(360deg) translateY($arc_radius);
|
||||
}
|
||||
|
||||
/*
|
||||
Some overrides.
|
||||
*/
|
||||
.reactor-container.active {
|
||||
$arc_radius: 130px;
|
||||
$size3: 6px;
|
||||
$cshadow: rgba(2, 254, 255, 0.8);
|
||||
$marks_color_1: rgba(2, 254, 255, 1);
|
||||
$marks_color_2: rgba(2, 254, 255, 0.3);
|
||||
$colour1: rgba(2, 255, 255, 0.15);
|
||||
$colour3: rgba(2, 255, 255, 0.3);
|
||||
$cshadow: rgba(2, 254, 255, 0.8);
|
||||
|
||||
scale: 1.1;
|
||||
opacity: 1;
|
||||
.coil-container {
|
||||
animation: 3s infinite linear reactor-anim;
|
||||
}
|
||||
|
||||
.reactor-container-inner {
|
||||
box-shadow: 0px 0px 50px 15px $colour3, inset 0px 0px 50px 15px $colour3;
|
||||
}
|
||||
|
||||
.core-inner {
|
||||
border: 5px solid #1b4e5f;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 7px 5px #52fefe, 0px 0px 10px 10px #52fefe inset;
|
||||
}
|
||||
|
||||
.core-outer {
|
||||
border: 1px solid #52fefe;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 2px 1px #52fefe, 0px 0px 10px 5px #52fefe inset;
|
||||
}
|
||||
.core-wrapper {
|
||||
background-color: #073c4b;
|
||||
box-shadow: 0px 0px 5px 4px #52fefe, 0px 0px 6px 2px #52fefe inset;
|
||||
}
|
||||
.tunnel {
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 5px 1px #52fefe, 0px 0px 5px 4px #52fefe inset;
|
||||
}
|
||||
.coil {
|
||||
background-color: #073c4b;
|
||||
box-shadow: 0px 0px 5px #52fefe inset;
|
||||
}
|
||||
|
||||
.semi_arc {
|
||||
border: 6px solid #02feff;
|
||||
background: rgba(2, 254, 255, 0.2);
|
||||
}
|
||||
|
||||
|
||||
.e5_1 {
|
||||
animation: rotate 3s linear infinite;
|
||||
}
|
||||
|
||||
.e5_2 {
|
||||
animation: rotate_anti 2s linear infinite;
|
||||
}
|
||||
|
||||
.e5_3 {
|
||||
animation: rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.e5_4 {
|
||||
animation: rotate_anti 2s linear infinite;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
18
frontend/_src/components/elements/HDivider.svelte
Normal file
18
frontend/_src/components/elements/HDivider.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<script>
|
||||
export let no_margin = false;
|
||||
</script>
|
||||
|
||||
<div class="h-divider" class:no-margin="{no_margin}"></div>
|
||||
|
||||
<style lang="scss">
|
||||
.h-divider {
|
||||
margin: 20px 0;
|
||||
height: 40px;
|
||||
background-image: url(media/images/decor.png);
|
||||
background-position: center;
|
||||
|
||||
&.no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
11
frontend/_src/components/elements/SearchBar.svelte
Normal file
11
frontend/_src/components/elements/SearchBar.svelte
Normal file
@@ -0,0 +1,11 @@
|
||||
<script>
|
||||
let search_q = "";
|
||||
</script>
|
||||
|
||||
<div id="search-form" class="search" class:active={search_q != ""}>
|
||||
<form action="#" method="GET">
|
||||
<input bind:value={search_q} type="text" name="q" placeholder="Введите команду или скажите «Джарвис» ..." autocomplete="off" minlength="3" maxlength="30">
|
||||
<button type="submit"></button>
|
||||
<small>Enter</small>
|
||||
</form>
|
||||
</div>
|
||||
377
frontend/_src/components/elements/Stats.svelte
Normal file
377
frontend/_src/components/elements/Stats.svelte
Normal file
@@ -0,0 +1,377 @@
|
||||
<script>
|
||||
// IMPORTS
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { onMount } from 'svelte'
|
||||
import { capitalizeFirstLetter } from "@/functions";
|
||||
|
||||
// VARIABLES
|
||||
let selected_microphone = 0;
|
||||
let microphone_label = "";
|
||||
|
||||
let nn_details = {
|
||||
"ww_engine": "",
|
||||
"stt_engine": "Vosk"
|
||||
}
|
||||
|
||||
// let resources_cpu_temp = 0;
|
||||
// let resources_cpu_usage = 0;
|
||||
let resources_ram_usage = "-";
|
||||
|
||||
// CODE
|
||||
setInterval(() => {
|
||||
(async () => {
|
||||
resources_ram_usage = Number(await invoke("get_current_ram_usage")).toFixed(2);
|
||||
// resources_cpu_temp = await invoke("get_cpu_temp");
|
||||
// resources_cpu_usage = +Number(await invoke("get_cpu_usage")).toFixed(2);
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
onMount(async () => {
|
||||
(async () => {
|
||||
selected_microphone = +Number(await invoke("db_read", {key: "selected_microphone"}));
|
||||
microphone_label = await invoke("pv_get_audio_device_name", {idx: selected_microphone});
|
||||
|
||||
nn_details["ww_engine"] = capitalizeFirstLetter(await invoke("db_read", {key: "selected_wake_word_engine"}));
|
||||
|
||||
// resources_cpu_temp = await invoke("get_cpu_temp");
|
||||
// resources_cpu_usage = +Number(await invoke("get_cpu_usage")).toFixed(2);
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="statistics">
|
||||
<div class="online">
|
||||
<div class="pulse"><div class="wave"></div></div>
|
||||
<div class="info">
|
||||
<span class="num">Микрофон</span>
|
||||
<small title="{microphone_label}">{microphone_label}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="files">
|
||||
<div class="pulse"><div class="wave"></div></div>
|
||||
<div class="info">
|
||||
<span class="num">Нейросети</span>
|
||||
<small>{nn_details["ww_engine"]} + {nn_details["stt_engine"]}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="downloads hint--bottom" aria-label="Общее количество скачиваний по всему проекту">
|
||||
<div class="pulse"><div class="wave"></div></div>
|
||||
<div class="info">
|
||||
<span class="num">Ресурсы</span>
|
||||
<small><!-- CPU {resources_cpu_usage}%<br /> -->RAM {resources_ram_usage}mb</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.statistics {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
padding: 0 10px;
|
||||
height: 100px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
& > div {
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.info {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
& > .online {
|
||||
position: relative;
|
||||
width: 40%;
|
||||
|
||||
$base-color: rgba(0, 191, 8, 1);
|
||||
$mid-color: rgba(0, 191, 8, 0.4);
|
||||
$end-color: rgba(0, 191, 8, 0);
|
||||
|
||||
& > .pulse::before {
|
||||
background-color: rgba(0, 191, 8, 1);
|
||||
}
|
||||
& > .pulse::after {
|
||||
background-color: rgba(0, 191, 8, 1);
|
||||
animation: online-cdot linear 3s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
& > .pulse .wave {
|
||||
background-color: rgba(0, 191, 8, 0.4);
|
||||
animation: online-radarWave cubic-bezier(0, 0.54, 0.53, 1) 3s 0s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
& > .pulse .wave::after {
|
||||
background-color: rgba(0, 191, 8, 0.4);
|
||||
animation: online-radarWave cubic-bezier(0, 0.54, 0.53, 1) 3s
|
||||
0.1s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
& > .info {
|
||||
position: absolute;
|
||||
top: 26px;
|
||||
left: 26px;
|
||||
|
||||
& > span.num {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #00bf08;
|
||||
}
|
||||
& > small {
|
||||
display: block;
|
||||
color: #535a60;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
top: 0;
|
||||
width: 130px;
|
||||
max-height: 40px;
|
||||
overflow: hidden;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes online-cdot {
|
||||
0% {
|
||||
opacity: 0.3;
|
||||
background: $base-color;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
background: $end-color;
|
||||
}
|
||||
}
|
||||
@keyframes online-radarWave {
|
||||
0% {
|
||||
opacity: 0.1;
|
||||
transform: scale(0);
|
||||
}
|
||||
5% {
|
||||
background: $mid-color;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.2);
|
||||
background: $end-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .files {
|
||||
position: relative;
|
||||
width: 35%;
|
||||
|
||||
$base-color: rgba(255, 129, 48, 1);
|
||||
$mid-color: rgba(255, 129, 48, 0.4);
|
||||
$end-color: rgba(255, 129, 48, 0);
|
||||
|
||||
& > .pulse::before {
|
||||
background-color: $base-color;
|
||||
}
|
||||
& > .pulse::after {
|
||||
background-color: $base-color;
|
||||
animation: files-cdot linear 5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
& > .pulse .wave {
|
||||
background-color: $mid-color;
|
||||
animation: files-radarWave cubic-bezier(0, 0.54, 0.53, 1) 5s 0s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
& > .pulse .wave::after {
|
||||
background-color: $mid-color;
|
||||
animation: files-radarWave cubic-bezier(0, 0.54, 0.53, 1) 5s
|
||||
0.1s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
& > .info {
|
||||
position: absolute;
|
||||
top: 26px;
|
||||
left: 26px;
|
||||
|
||||
& > span.num {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #ff8130;
|
||||
}
|
||||
& > small {
|
||||
display: block;
|
||||
color: #535a60;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes files-cdot {
|
||||
0% {
|
||||
opacity: 0.3;
|
||||
background: $base-color;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
background: $end-color;
|
||||
}
|
||||
}
|
||||
@keyframes files-radarWave {
|
||||
0% {
|
||||
opacity: 0.1;
|
||||
transform: scale(0);
|
||||
}
|
||||
5% {
|
||||
background: $mid-color;
|
||||
transform: scale(0.2);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(0.8);
|
||||
background: $end-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > .downloads {
|
||||
position: relative;
|
||||
|
||||
$base-color: rgba(11,66,166, 1);
|
||||
$mid-color: rgba(32, 150, 243, 0.4);
|
||||
$end-color: rgba(32, 150, 243, 0);
|
||||
|
||||
& > .pulse::before {
|
||||
background: rgba(32, 150, 243, 1);
|
||||
}
|
||||
& > .pulse::after {
|
||||
background: rgba(32, 150, 243, 1);
|
||||
animation: downloads-cdot linear 7s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-fill-mode: forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
& > .pulse .wave {
|
||||
background-color: $mid-color;
|
||||
animation: downloads-radarWave cubic-bezier(0, 0.54, 0.53, 1) 7s
|
||||
0s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
& > .pulse .wave::after {
|
||||
background-color: $mid-color;
|
||||
animation: downloads-radarWave cubic-bezier(0, 0.54, 0.53, 1) 7s
|
||||
0.1s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
& > .info {
|
||||
position: absolute;
|
||||
top: 26px;
|
||||
left: 26px;
|
||||
|
||||
& > span.num {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #1b78a6;
|
||||
}
|
||||
|
||||
& > small {
|
||||
display: block;
|
||||
color: #535a60;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes downloads-cdot {
|
||||
0% {
|
||||
opacity: 0.3;
|
||||
background: $base-color;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
background: $end-color;
|
||||
}
|
||||
}
|
||||
@keyframes downloads-radarWave {
|
||||
0% {
|
||||
opacity: 0.1;
|
||||
transform: scale(0);
|
||||
}
|
||||
5% {
|
||||
background: $mid-color;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(0.7);
|
||||
background: $end-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pulse {
|
||||
position: relative;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
margin: 0;
|
||||
left: -43px;
|
||||
top: 0px;
|
||||
z-index: 5;
|
||||
}
|
||||
.pulse::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
border-radius: 50%;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
opacity: .5;
|
||||
}
|
||||
.pulse::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.pulse .wave {
|
||||
position: absolute;
|
||||
left: 7%;
|
||||
top: 7%;
|
||||
width: 86%;
|
||||
height: 86%;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
}
|
||||
.pulse .wave::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 7%;
|
||||
top: 7%;
|
||||
width: 86%;
|
||||
height: 86%;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
308
frontend/_src/css/main.scss
Normal file
308
frontend/_src/css/main.scss
Normal file
@@ -0,0 +1,308 @@
|
||||
$prim-font: "Roboto", sans-serif;
|
||||
$sec-font: "Roboto Condensed", sans-serif;
|
||||
|
||||
html, body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: -webkit-gradient(linear,left top,left bottom,from(#999),to(#27292F));
|
||||
background: linear-gradient(to bottom,#999,#27292F);
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: #FF8901!important; /* WebKit/Blink Browsers */
|
||||
color: white!important;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, .5)!important;
|
||||
}
|
||||
::-moz-selection {
|
||||
background: #FF8901!important; /* WebKit/Blink Browsers */
|
||||
color: white!important;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, .5)!important;
|
||||
}
|
||||
|
||||
/*
|
||||
* HEADER
|
||||
*/
|
||||
|
||||
#header {
|
||||
height: 80px;
|
||||
background-color: #0c1013;
|
||||
box-shadow: 0 0 19px 2px rgba(0, 0, 0, 0.91);
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
text-align: justify;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.logo {
|
||||
margin-top: 12px;
|
||||
|
||||
& > a > img {
|
||||
width: 57px;
|
||||
display: inline-block;
|
||||
transition: .5s opacity ease-in;
|
||||
|
||||
&:hover {
|
||||
opacity: .8;
|
||||
}
|
||||
}
|
||||
|
||||
& > div {
|
||||
display: inline-block;
|
||||
margin-left: 13px;
|
||||
margin-top: 8px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #ffffff;
|
||||
font-family: $sec-font;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1px;
|
||||
margin: 0;
|
||||
|
||||
& > a {
|
||||
color: white;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, .5);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #8AC832;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #888;
|
||||
font-family: $sec-font;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.1px;
|
||||
margin-top: 2px;
|
||||
letter-spacing: -0.01px;
|
||||
}
|
||||
}
|
||||
|
||||
.top-menu {
|
||||
vertical-align: top;
|
||||
margin-top: 18px;
|
||||
margin-left: 50px;
|
||||
|
||||
& > ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
& > li {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
& > a {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
color: #c6c6c6;
|
||||
font-family: $sec-font;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
transition: .2s color;
|
||||
padding: 10px 0;
|
||||
|
||||
& > svg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 4px;
|
||||
margin-right: 3px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
&:hover, &.active {
|
||||
color: #8AC832;
|
||||
|
||||
&:after {
|
||||
-webkit-transform: scaleX(1);
|
||||
-ms-transform: scaleX(1);
|
||||
transform: scaleX(1);
|
||||
-webkit-transform-origin: left;
|
||||
-ms-transform-origin: left;
|
||||
transform-origin: left;
|
||||
}
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: block;
|
||||
height: 3px;
|
||||
border-radius: 10px;
|
||||
-webkit-transform: scaleX(0);
|
||||
-ms-transform: scaleX(0);
|
||||
transform: scaleX(0);
|
||||
transition: .4s -webkit-transform;
|
||||
transition: .4s transform;
|
||||
-webkit-transform-origin: 100% 0;
|
||||
-ms-transform-origin: 100% 0;
|
||||
transform-origin: 100% 0;
|
||||
background: #8AC832;
|
||||
opacity: 0.90;
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 333;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
display: block;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
|
||||
& > form {
|
||||
position: relative;
|
||||
|
||||
& > input {
|
||||
width: 380px;
|
||||
height: 38px;
|
||||
box-shadow: inset 0 0 5px 1px rgba(0, 0, 0, 0.6);
|
||||
border: 1px solid rgba(6, 6, 6, 0.99);
|
||||
background-color: #0f1012;
|
||||
outline: none;
|
||||
|
||||
color: #D1D1D1;
|
||||
font-family: $sec-font;
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
line-height: 70.58px;
|
||||
padding-left: 20px;
|
||||
padding-right: 45px;
|
||||
padding-right: 45px;
|
||||
|
||||
&::placeholder {
|
||||
color: #676767;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&:focus + button + small {
|
||||
opacity: .3;
|
||||
}
|
||||
}
|
||||
|
||||
& > button {
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
right: 35px;
|
||||
top: 4px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
opacity: 1;
|
||||
transition: .3s opacity;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 110%;
|
||||
height: 110%;
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAbCAYAAABvCO8sAAAC4ElEQVRIiaXWX4hXRRTA8c/etkwy+gNBEVRCmxFl1ouZGlEWFUQZPfVQRLAjKvSylEFBf16EiChJOxhLQY8RtA+lRZtpRv8ohUJQNMiHooKyojZNtoeZy95+/fZ3r+uBy5xz5pzznYGZc2dodHRUB1lVviUYwXkYwk84iK8wGRHb2goNtQDXYxRXdVkV9mFrRDx/osCl2IxrG75PsAv75Z1NyzsdwQosb8R+jXURsbML8AG82rDH8TI+77eyiAAppSVYg9SYXhsRW5rxVU/+Qw3Yd7ip+PrCesB7ImKNvNMDxb05pbR+NuBSvFL0L7EYH7SB+oA/Lrm7i2tTSmlVL3AYbxf9eyzDkROFNaBTWCmfYJhIKc1rAh/DuUW/HUfnCmtAp3FrMefjmRp4Kh4tE+PYO6DO6fKp7Ao9hJeKOZZSWlBhNc4ozidbaqyUr8W4/x+42aSuOYT7KtxZHF/gcEvyvDI+KF/yFW20iPgZk8W8o8KVxZjsn/IfOdbQL8OulNLTHfJ2lHFRhYuKcbB/bKs8kVLanVK6ZkBMfS8vqLCgGL/NEQjX48MB8/UVm1/hz2KceRLAfbh3wHxde2pYbmFnY+EcYVsiYm1LzKVl/KHCN8W4sUPxUxr6j7i7AwxuKOP+ykxLW4bzWxKnyziBRXirjZRSOstMx9lW4Q38XRyPt+R/hOtwF35tgzVqDhX99QpTeK441pWVzya/49OOICmlCzFWzE0RcaRuT0/hj6Jv71qwg7xbxuNKv66BR820uIuxE6edDCmltB1XFPOeiPiL/B+sZQcexgtyk96L+3X42/eAFuM1+YUHGyJiop4f7ol/Ef/Iv5TL8VlZQMiXexBoRH7hjTXcj0TEs8242V5tNxdo8wC9J5/Sfq+25bitEfut/Gp7p7dw7w5reV/e4Yay6oW4pXyD5DC2YmNEHOsXMBuwlo3lWy3v+mpcgnPku/WL3Br3yA+uNyPi+KCC/wJQGMGINsMjCwAAAABJRU5ErkJggg==");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 75%;
|
||||
background-position: center center;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::before {
|
||||
cursor: pointer;
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAbCAYAAABvCO8sAAABN2lDQ1BBZG9iZSBSR0IgKDE5OTgpAAAokZWPv0rDUBSHvxtFxaFWCOLgcCdRUGzVwYxJW4ogWKtDkq1JQ5ViEm6uf/oQjm4dXNx9AidHwUHxCXwDxamDQ4QMBYvf9J3fORzOAaNi152GUYbzWKt205Gu58vZF2aYAoBOmKV2q3UAECdxxBjf7wiA10277jTG+38yH6ZKAyNguxtlIYgK0L/SqQYxBMygn2oQD4CpTto1EE9AqZf7G1AKcv8ASsr1fBBfgNlzPR+MOcAMcl8BTB1da4Bakg7UWe9Uy6plWdLuJkEkjweZjs4zuR+HiUoT1dFRF8jvA2AxH2w3HblWtay99X/+PRHX82Vun0cIQCw9F1lBeKEuf1UYO5PrYsdwGQ7vYXpUZLs3cLcBC7dFtlqF8hY8Dn8AwMZP/fNTP8gAAAAJcEhZcwAACxMAAAsTAQCanBgAAAXRaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0MiA3OS4xNjA5MjQsIDIwMTcvMDcvMTMtMDE6MDY6MzkgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjMtMDQtMjNUMDQ6MzE6NTgrMDU6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIzLTA0LTIzVDA0OjM0OjI3KzA1OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIzLTA0LTIzVDA0OjM0OjI3KzA1OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowZDA5NTdiMi0zYmM3LTcxNDItODcyNS01ODA3MjA2NTFlYTIiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDoxM2UwZWYxNi03OGM0LTE2NGMtODc1Mi0xYjY5OTQ1OTczMGMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5YjNkZTI4Yy1iOTBmLTNjNDUtYjAwNS1kNTExOTE3ZDhkNzIiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjliM2RlMjhjLWI5MGYtM2M0NS1iMDA1LWQ1MTE5MTdkOGQ3MiIgc3RFdnQ6d2hlbj0iMjAyMy0wNC0yM1QwNDozMTo1OCswNTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowZDA5NTdiMi0zYmM3LTcxNDItODcyNS01ODA3MjA2NTFlYTIiIHN0RXZ0OndoZW49IjIwMjMtMDQtMjNUMDQ6MzQ6MjcrMDU6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Wh528AAAC7UlEQVRIiaXWX4gXVRTA8c9v2jLJ6A8ERVAJbUakTr2YqRFl0QRRRk89FBGYqNDLUgY51PQiRERJWhhLQY8RtA+OFm2mGf2RGqEQDAvyoaigrKhNk+3h3mGnX7/9zbgeGO45555zvvfCvWdub/POpTrI6vilGMVF6OEnHMEXmCyyaldboV4LcCPWYnGXVeEQdhRZ9fypApdhG65v+D7GPhwWdjYt7HQUK7GiEfslNhRZtbcL8EG81rDH8TI+G7SyIqtAXqYp1uGRxvT6Iqu2N+OTvvyHG7DvcEv0DYT1gasiq9YJO/06urflZbpxNuAyvBr1z7EE77eBBoA/irn7o2trXqar+4Ej2Bn177Ecx04V1oBOYZVwgmEiL9N5TeATuDDqGY7PFdaATuP2aM7HMzXwTDweJ8ZxcEids4VT2RX6DV6K5lhepgsSrME50flUS41VwrUY9/8DN5vUNXu4P8Fd0XEAR1uS58XxIeGSr2yjFVn1MyajeWeCa6MxOTjlP3KioV+FfXmZFh3y9sRxUYLLonFkcGyrbM7LdH9eptcNianv5SUJFkTjtzkC4UZ8MGS+vmLzE/wZjXNPA3gI9w2Zr2tPjQgt7HwsnCNse5FV61tirozjDwm+isbNHYqf0dB/xD0dYHBTHA8nZlraclzckjgdxwkswtttpLxMzzPTcXYleBN/R8eTLfkf4gbcjV/bYI2avai/kWAKz0XHhrjy2eR3fNIRJC/TSzEWza1FVh2r29PT+CPqu7sW7CDvxPGk2K9r4HEzLe5y7MVZp0PKy3Q3ronmvUVW/UX4D9ayB4/iBaFJH8QDOvzt+0BL8LrwwoNNRVZN1PMjffEv4h/hl3I1Po0LeEW43MNAo8ILb6zhfqzIqmebcbO92m6N0OYBelc4pYNebStwRyP2W+HVVvYX7t9hLe8JO9wUV70Qt8VvmBzFDmwpsurEoIDZgLVsid8aYddLcQUuEO7WL0JrrIQH11tFVp0cVvBfVZDA+HDoxOQAAAAASUVORK5CYII=");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > small {
|
||||
position: absolute;
|
||||
font-family: $sec-font;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
line-height: 1.7em;
|
||||
top: 8px;
|
||||
right: 75px;
|
||||
background-color: #D1D1D1;
|
||||
color: #080C0F;
|
||||
padding: 0 7px;
|
||||
padding-top: 2px;
|
||||
border-radius: 4px;
|
||||
opacity: 0;
|
||||
transition: opacity .3s;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
small {
|
||||
opacity: .3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1364px) {
|
||||
#content>.inner>section.materials>header>h1 {
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
#content>.inner>section.materials>article>.details>h1 {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
#content>.inner>section.materials>article>.details>blockquote {
|
||||
font-size: 17px;
|
||||
line-height: 24px;
|
||||
-webkit-line-clamp: 4;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 16px!important;
|
||||
}
|
||||
|
||||
#paginator>header>h1 {
|
||||
font-size: 30px!important;
|
||||
}
|
||||
|
||||
#paginator>.paginator-wrapper>.paginator-box {
|
||||
transform: scale(1.5);
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#paginator>.paginator-wrapper>small:first-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#paginator>.paginator-wrapper>small:last-child {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
92
frontend/_src/css/styles.scss
Normal file
92
frontend/_src/css/styles.scss
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
SOME DEFAULT CSS.
|
||||
*/
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
min-width: 100vw;
|
||||
|
||||
background-color: #4C5062;
|
||||
color: white;
|
||||
|
||||
|
||||
&.assist-page {
|
||||
background: rgb(24,123,123);
|
||||
background: -moz-radial-gradient(circle, rgba(24,123,123,0.4906337535014006) 0%, rgba(13,15,19,1) 64%);
|
||||
background: -webkit-radial-gradient(circle, rgba(24,123,123,0.4906337535014006) 0%, rgba(13,15,19,1) 64%);
|
||||
background: radial-gradient(circle, rgba(24,123,123,0.4906337535014006) 0%, rgba(13,15,19,1) 64%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#187b7b",endColorstr="#0d0f13",GradientType=1);
|
||||
|
||||
&.assist-active {
|
||||
background: rgb(24,81,123);
|
||||
background: -moz-radial-gradient(circle, rgba(24,81,123,0.6418942577030813) 0%, rgba(13,15,19,1) 64%);
|
||||
background: -webkit-radial-gradient(circle, rgba(24,81,123,0.6418942577030813) 0%, rgba(13,15,19,1) 64%);
|
||||
background: radial-gradient(circle, rgba(24,81,123,0.6418942577030813) 0%, rgba(13,15,19,1) 64%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#18517b",endColorstr="#0d0f13",GradientType=1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
|
||||
color: #0f0f0f;
|
||||
background-color: #f6f6f6;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: #2A9CD0;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
color: #1dabed;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
OVERRIDES.
|
||||
*/
|
||||
#wrapper {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#header, main {
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
select, input {
|
||||
color: #ccc!important;
|
||||
}
|
||||
|
||||
.form {
|
||||
label {
|
||||
font-weight: bold!important;
|
||||
color: #8AC832!important;
|
||||
font-size: 15px!important;
|
||||
border-bottom: 1px dotted gray;
|
||||
margin-bottom: 10px!important;
|
||||
|
||||
& + div {
|
||||
line-height: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.svelteui-Tab-label {
|
||||
font-size: 18px!important;
|
||||
}
|
||||
}
|
||||
61
frontend/_src/functions.ts
Normal file
61
frontend/_src/functions.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { is_listening, isListening } from "@/stores"
|
||||
import { clearInterval, clearTimeout, setInterval, setTimeout } from 'worker-timers';
|
||||
|
||||
// setInterval(() => {
|
||||
// (async () => {
|
||||
// is_listening.set(await invoke("is_listening"));
|
||||
// })().catch(err => {
|
||||
// console.error(err);
|
||||
// });
|
||||
// }, 1000);
|
||||
|
||||
export function startListening() {
|
||||
(async () => {
|
||||
invoke('start_listening')
|
||||
.then((message) => {
|
||||
is_listening.set(true);
|
||||
})
|
||||
.catch((error) => {
|
||||
is_listening.set(false);
|
||||
console.error(error);
|
||||
// alert("Ошибка: " + error);
|
||||
})
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
export function stopListening(callback: () => void) {
|
||||
(async () => {
|
||||
invoke('stop_listening')
|
||||
.then((message) => {
|
||||
is_listening.set(false);
|
||||
if(callback) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
})
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
export function capitalizeFirstLetter(string: string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
export function showInExplorer(path: any) {
|
||||
(async () => {
|
||||
invoke('show_in_folder', {path: path})
|
||||
.then((message) => {})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
// alert("Ошибка: " + error);
|
||||
})
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
13
frontend/_src/main.ts
Normal file
13
frontend/_src/main.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
// Klondike project old CSS file
|
||||
import "./css/main.scss";
|
||||
|
||||
// App current CSS file
|
||||
import "./css/styles.scss";
|
||||
|
||||
// deploy app
|
||||
import App from "./App.svelte";
|
||||
const app = new App({
|
||||
target: document.getElementById("app")!,
|
||||
});
|
||||
|
||||
export default app;
|
||||
12
frontend/_src/routes/_module.svelte
Normal file
12
frontend/_src/routes/_module.svelte
Normal file
@@ -0,0 +1,12 @@
|
||||
<!-- _layout.svelte -->
|
||||
<script>
|
||||
import { Container } from '@svelteuidev/core'
|
||||
import Header from '@/components/Header.svelte'
|
||||
</script>
|
||||
|
||||
<Container fluid id="wrapper">
|
||||
<Header />
|
||||
<main>
|
||||
<slot></slot>
|
||||
</main>
|
||||
</Container>
|
||||
23
frontend/_src/routes/commands/index.svelte
Normal file
23
frontend/_src/routes/commands/index.svelte
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
import HDivider from "@/components/elements/HDivider.svelte"
|
||||
import Footer from "@/components/Footer.svelte"
|
||||
|
||||
import { Notification, Space } from '@svelteuidev/core';
|
||||
import { InfoCircled } from 'radix-icons-svelte';
|
||||
|
||||
import { tg_official_link } from "@/stores";
|
||||
</script>
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<Notification title='[404] Этот раздел еще находится в разработке!' icon={InfoCircled} color='blue' withCloseButton={false}>
|
||||
Тут будет список команд + полноценный редактор команд.<br>
|
||||
Следите за обновлениями в <a href="{tg_official_link}" target="_blank">нашем телеграм канале</a>!
|
||||
</Notification>
|
||||
|
||||
<div style="text-align: center;margin-top: 25px;">
|
||||
<img src="/media/images/tenor.gif" alt="bruh" width="320px">
|
||||
</div>
|
||||
|
||||
<HDivider />
|
||||
<Footer />
|
||||
71
frontend/_src/routes/index.svelte
Normal file
71
frontend/_src/routes/index.svelte
Normal file
@@ -0,0 +1,71 @@
|
||||
<script lang="ts">
|
||||
import SearchBar from "@/components/elements/SearchBar.svelte"
|
||||
import ArcReactor from "@/components/elements/ArcReactor.svelte"
|
||||
import HDivider from "@/components/elements/HDivider.svelte"
|
||||
import Stats from "@/components/elements/Stats.svelte"
|
||||
import Footer from "@/components/Footer.svelte"
|
||||
|
||||
import { Notification, Space } from '@svelteuidev/core'
|
||||
import { InfoCircled } from 'radix-icons-svelte'
|
||||
import { onMount, onDestroy } from 'svelte'
|
||||
|
||||
onMount(async () => {
|
||||
document.body.classList.add('assist-page');
|
||||
});
|
||||
|
||||
onDestroy(async () => {
|
||||
document.body.classList.remove('assist-page');
|
||||
});
|
||||
|
||||
import { is_listening } from "@/stores"
|
||||
let is_listening__val: boolean;
|
||||
is_listening.subscribe(value => {
|
||||
is_listening__val = value;
|
||||
});
|
||||
</script>
|
||||
|
||||
<HDivider />
|
||||
{#if !is_listening__val}
|
||||
<Notification title='Внимание!' icon={InfoCircled} color='cyan' withCloseButton={false}>
|
||||
В данный момент ассистент не прослушивает команды.<br />
|
||||
Пожалуйста, <a href="/settings">перейдите в настройки</a> и введите ключ Picovoice.
|
||||
</Notification>
|
||||
<!-- <SearchBar /> -->
|
||||
{:else}
|
||||
<!-- <SearchBar /> -->
|
||||
<ArcReactor />
|
||||
{/if}
|
||||
<HDivider no_margin />
|
||||
<Stats />
|
||||
<Footer />
|
||||
|
||||
|
||||
<!--
|
||||
<Title order={1}>This is h1 title</Title>
|
||||
<Title order={1} variant='gradient' gradient={{from: 'blue', to: 'red', deg: 45}}>This is h1 title with a twist</Title>
|
||||
|
||||
<Menu>
|
||||
<Button slot="control" variant="gradient" gradient={{ from: 'blue', to: 'teal', deg: 50 }} radius="md" size="md">Toggle Menu</Button>
|
||||
<Menu.Label>Application</Menu.Label>
|
||||
<Menu.Item icon={Gear}>Settings</Menu.Item>
|
||||
<Menu.Item icon={ChatBubble}>Messages</Menu.Item>
|
||||
<Menu.Item icon={Camera}>Gallery</Menu.Item>
|
||||
<Menu.Item icon={MagnifyingGlass}>
|
||||
<svelte:fragment slot='rightSection'>
|
||||
<Text size="xs" color="dimmed">⌘K</Text>
|
||||
</svelte:fragment>
|
||||
Search
|
||||
</Menu.Item>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Menu.Label>Danger zone</Menu.Label>
|
||||
<Menu.Item icon={Width}>Transfer my data</Menu.Item>
|
||||
<Menu.Item color="red" icon={Trash}>Delete my account</Menu.Item>
|
||||
</Menu>
|
||||
|
||||
<Checkbox bind:checked={checked} label="I agree to sell my privacy" />
|
||||
{checked}
|
||||
{#if checked}
|
||||
YEP!
|
||||
{/if} -->
|
||||
188
frontend/_src/routes/settings/index.svelte
Normal file
188
frontend/_src/routes/settings/index.svelte
Normal file
@@ -0,0 +1,188 @@
|
||||
<script lang="ts">
|
||||
// IMPORTS
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { goto } from '@roxi/routify'
|
||||
import { onMount } from 'svelte'
|
||||
import { startListening, stopListening, showInExplorer } from "@/functions";
|
||||
// import { setTimeout } from 'worker-timers';
|
||||
|
||||
import { feedback_link, log_file_path } from "@/stores";
|
||||
|
||||
// COMPONENTS & STUFF
|
||||
import HDivider from "@/components/elements/HDivider.svelte"
|
||||
import Footer from "@/components/Footer.svelte"
|
||||
|
||||
import { Notification, Button, Text, Tabs, Space, Alert, Input, InputWrapper, NativeSelect } from '@svelteuidev/core';
|
||||
import { Check, Mix, Cube, Code, Gear, QuestionMarkCircled, CrossCircled } from 'radix-icons-svelte';
|
||||
|
||||
// VARIABLES
|
||||
|
||||
let available_microphones: { label: string; value: number }[] = [];
|
||||
let settings_saved = false;
|
||||
let save_button_disabled = false;
|
||||
|
||||
let assistant_voice_val = ""; // shared
|
||||
let selected_microphone = "";
|
||||
|
||||
let selected_wake_word_engine = "";
|
||||
let api_key__picovoice = "";
|
||||
let api_key__openai = "";
|
||||
|
||||
// SHARED VALUES
|
||||
import { assistant_voice } from "@/stores"
|
||||
assistant_voice.subscribe(value => {
|
||||
assistant_voice_val = value;
|
||||
});
|
||||
|
||||
// FUNCTIONS
|
||||
async function save_settings() {
|
||||
save_button_disabled = true; // disable save button for a while
|
||||
settings_saved = false; // hide alert
|
||||
|
||||
await invoke("db_write", {key: "assistant_voice", val: assistant_voice_val});
|
||||
await invoke("db_write", {key: "selected_microphone", val: selected_microphone});
|
||||
|
||||
await invoke("db_write", {key: "selected_wake_word_engine", val: selected_wake_word_engine});
|
||||
await invoke("db_write", {key: "api_key__picovoice", val: api_key__picovoice});
|
||||
await invoke("db_write", {key: "api_key__openai", val: api_key__openai});
|
||||
|
||||
// update shared
|
||||
assistant_voice.set(assistant_voice_val);
|
||||
|
||||
settings_saved = true; // show alert
|
||||
setTimeout(() => {
|
||||
settings_saved = false; // hide alert again after N seconds
|
||||
}, 5000);
|
||||
|
||||
setTimeout(() => {
|
||||
save_button_disabled = false; // enable save button again
|
||||
}, 1000);
|
||||
|
||||
// restart listening everytime new settings is saved
|
||||
stopListening(() => {
|
||||
startListening();
|
||||
});
|
||||
}
|
||||
|
||||
// CODE
|
||||
onMount(async () => {
|
||||
// preload some vars
|
||||
let _available_microphones: Array<Number> = await invoke("pv_get_audio_devices");
|
||||
Object.entries(_available_microphones).forEach(entry => {
|
||||
const [k, v] = entry;
|
||||
|
||||
available_microphones.push({
|
||||
label: String(v),
|
||||
value: Number(k)
|
||||
});
|
||||
});
|
||||
|
||||
available_microphones = available_microphones; // update component options
|
||||
|
||||
// load values from db
|
||||
// assistant_voice.set(await invoke("db_read", {key: "assistant_voice"}));
|
||||
selected_microphone = await invoke("db_read", {key: "selected_microphone"});
|
||||
|
||||
selected_wake_word_engine = await invoke("db_read", {key: "selected_wake_word_engine"});
|
||||
api_key__picovoice = await invoke("db_read", {key: "api_key__picovoice"});
|
||||
api_key__openai = await invoke("db_read", {key: "api_key__openai"});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<Notification title='БЕТА версия!' icon={QuestionMarkCircled} color='blue' withCloseButton={false}>
|
||||
Часть функций может работать некорректно.<br />
|
||||
Сообщайте обо всех найденных багах в <a href="{feedback_link}" target="_blank">наш телеграм бот</a>.
|
||||
<Space h="sm" />
|
||||
<Button color="gray" radius="md" size="xs" uppercase on:click={() => {showInExplorer(log_file_path)}}>Открыть папку с логами</Button>
|
||||
</Notification>
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
{#if settings_saved }
|
||||
<Notification title='Настройки сохранены!' icon={Check} color='teal' on:close="{() => {settings_saved = false}}"></Notification>
|
||||
<Space h="xl" />
|
||||
{/if}
|
||||
|
||||
<Tabs class="form" color='#8AC832' position="left">
|
||||
<Tabs.Tab label='Общее' icon={Gear}>
|
||||
<Space h="sm" />
|
||||
|
||||
<NativeSelect data={[
|
||||
{ label: 'Jarvis ремейк (от Хауди)', value: 'jarvis-remake' },
|
||||
{ label: 'Jarvis OG (из фильмов)', value: 'jarvis-og' }
|
||||
]}
|
||||
label="Голос ассистента"
|
||||
description="Не все команды работают со всеми звуковыми пакетами."
|
||||
variant="filled"
|
||||
bind:value={assistant_voice_val}
|
||||
/>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab label='Устройства' icon={Mix}>
|
||||
<Space h="sm" />
|
||||
|
||||
<NativeSelect data={available_microphones}
|
||||
label="Выберите микрофон"
|
||||
description="Его будет слушать ассистент."
|
||||
variant="filled"
|
||||
bind:value={selected_microphone}
|
||||
/>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab label='Нейросети' icon={Cube}>
|
||||
<Space h="sm" />
|
||||
|
||||
<NativeSelect data={[
|
||||
{ label: 'Rustpotter', value: 'Rustpotter' },
|
||||
{ label: 'Vosk (медленный)', value: 'Vosk' },
|
||||
{ label: 'Picovoice Porcupine (требует API ключ)', value: 'Picovoice' }
|
||||
]}
|
||||
label="Распознавание активационной фразы (Wake Word)"
|
||||
description="Выберите, какая нейросеть будет отвечать за распознавание активационной фразы."
|
||||
variant="filled"
|
||||
bind:value={selected_wake_word_engine}
|
||||
/>
|
||||
|
||||
{#if selected_wake_word_engine == "picovoice"}
|
||||
<Space h="sm" />
|
||||
<Alert title="Внимание!" color="#868E96" variant="outline">
|
||||
|
||||
<Notification title='Эта нейросеть работает не у всех!' icon={CrossCircled} color='orange' withCloseButton={false}>
|
||||
Мы ждем официального патча от разработчиков.
|
||||
</Notification>
|
||||
<Space h="sm" />
|
||||
|
||||
<Text size='sm' color="gray">
|
||||
Введите сюда свой ключ Picovoice.<br />
|
||||
Он выдается бесплатно при регистрации в <a href='https://console.picovoice.ai/' target="_blank">Picovoice Console</a>.<br>
|
||||
</Text>
|
||||
<Space h="sm" />
|
||||
<Input icon={Code} placeholder='Ключ Picovoice' variant='filled' autocomplete="off" bind:value={api_key__picovoice}/>
|
||||
|
||||
</Alert>
|
||||
{/if}
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<InputWrapper label="Ключ OpenAI">
|
||||
<!-- <Text size='sm' color="gray">Введите сюда свой ключ OpenAI, он требуется для работы ChatGPT.<br />Получить его можно <a href="https://chat.openai.com/auth/login" target="_blank">на официальном сайте OpenAI</a>.</Text> -->
|
||||
<Text size='sm' color="gray">В данный момент ChatGPT <u>не поддерживается</u>. Он будет добавлен в ближайших обновлениях.</Text>
|
||||
<Space h="sm" />
|
||||
<Input icon={Code} placeholder='Ключ OpenAI' variant='filled' autocomplete="off" bind:value={api_key__openai} disabled/>
|
||||
</InputWrapper>
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<Button color="lime" radius="md" size="sm" uppercase ripple fullSize on:click={save_settings} disabled={save_button_disabled}>
|
||||
Сохранить
|
||||
</Button>
|
||||
<Space h="sm" />
|
||||
<Button color="gray" radius="md" size="sm" uppercase fullSize on:click={() => {$goto('/')}}>
|
||||
Назад
|
||||
</Button>
|
||||
|
||||
<HDivider />
|
||||
<Footer />
|
||||
34
frontend/_src/stores.ts
Normal file
34
frontend/_src/stores.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
// listen state
|
||||
export const is_listening = writable(true);
|
||||
let is_listening__val: boolean;
|
||||
is_listening.subscribe(value => {
|
||||
is_listening__val = value;
|
||||
});
|
||||
export function isListening() {return is_listening__val}
|
||||
|
||||
// assistant voice
|
||||
export const assistant_voice = writable("");
|
||||
|
||||
(async () => {
|
||||
assistant_voice.set(await invoke("db_read", {key: "assistant_voice"}));
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
// etc
|
||||
export let tg_official_link = "";
|
||||
export let feedback_link = "";
|
||||
export let github_repository_link = "";
|
||||
export let log_file_path = "";
|
||||
|
||||
(async () => {
|
||||
tg_official_link = await invoke("get_tg_official_link")
|
||||
feedback_link = await invoke("get_feedback_link")
|
||||
github_repository_link = await invoke("get_repository_link")
|
||||
log_file_path = await invoke("get_log_file_path")
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
2
frontend/_src/vite-env.d.ts
vendored
Normal file
2
frontend/_src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference types="svelte" />
|
||||
/// <reference types="vite/client" />
|
||||
@@ -1,18 +1,11 @@
|
||||
<!-- src/App.svelte -->
|
||||
<script>
|
||||
import { Router } from "@roxi/routify";
|
||||
import routes from "../.routify/routes.default.js";
|
||||
|
||||
import { SvelteUIProvider } from '@svelteuidev/core';
|
||||
|
||||
import Events from "./Events.svelte";
|
||||
|
||||
/** START LISTENING **/
|
||||
// import { startListening } from "./functions";
|
||||
// startListening();
|
||||
<script lang="ts">
|
||||
import { Router } from "@roxi/routify"
|
||||
import routes from "../.routify/routes.default.js"
|
||||
import { SvelteUIProvider } from "@svelteuidev/core"
|
||||
import Events from "./Events.svelte"
|
||||
</script>
|
||||
|
||||
<SvelteUIProvider themeObserver='dark' withNormalizeCSS withGlobalStyles>
|
||||
<SvelteUIProvider themeObserver="dark" withNormalizeCSS withGlobalStyles>
|
||||
<Router {routes} />
|
||||
</SvelteUIProvider>
|
||||
|
||||
|
||||
@@ -1,44 +1,34 @@
|
||||
<script>
|
||||
import { onMount, onDestroy } from 'svelte'
|
||||
import { emit, listen } from '@tauri-apps/api/event'
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte"
|
||||
import { listen } from "@tauri-apps/api/event"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { assistantVoice } from "@/stores"
|
||||
|
||||
import { resolveResource } from '@tauri-apps/api/path'
|
||||
|
||||
import {Howl, Howler} from 'howler';
|
||||
|
||||
let assistant_voice_val = "jarvis-og";
|
||||
import { assistant_voice } from "@/stores"
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
assistant_voice.subscribe(value => {
|
||||
assistant_voice_val = value;
|
||||
});
|
||||
let voiceVal = "jarvis-og"
|
||||
assistantVoice.subscribe(value => {
|
||||
voiceVal = value || "jarvis-og"
|
||||
})
|
||||
|
||||
onMount(async () => {
|
||||
await listen('audio-play', async (event) => {
|
||||
// event.event is the event name (useful if you want to use a single callback fn for multiple event types)
|
||||
// event.payload is the payload object
|
||||
// let path = await resolveResource('sound/' + (assistant_voice_val == "" ? "jarvis-remake":assistant_voice_val) + '/' + event.payload['data'] + '.wav');
|
||||
// console.log(path);
|
||||
// let sound = new Howl({
|
||||
// src: [path],
|
||||
// html5: true
|
||||
// });
|
||||
// audio playback event
|
||||
await listen<{ data: string }>("audio-play", async (event) => {
|
||||
const voice = voiceVal || "jarvis-remake"
|
||||
const filename = `sound/${voice}/${event.payload.data}.wav`
|
||||
|
||||
// sound.play();
|
||||
try {
|
||||
await invoke("play_sound", { filename, sleep: true })
|
||||
} catch (err) {
|
||||
console.error("failed to play sound:", err)
|
||||
}
|
||||
})
|
||||
|
||||
let filename = 'sound/' + (assistant_voice_val == "" ? "jarvis-remake":assistant_voice_val) + '/' + event.payload['data'] + '.wav';
|
||||
await invoke("play_sound", {
|
||||
filename: filename,
|
||||
sleep: true
|
||||
});
|
||||
});
|
||||
// assistant state events
|
||||
await listen("assistant-greet", () => {
|
||||
document.getElementById("arc-reactor")?.classList.add("active")
|
||||
})
|
||||
|
||||
await listen('assistant-greet', (event) => {
|
||||
document.getElementById("arc-reactor")?.classList.add("active");
|
||||
});
|
||||
|
||||
await listen('assistant-waiting', (event) => {
|
||||
document.getElementById("arc-reactor")?.classList.remove("active");
|
||||
});
|
||||
});
|
||||
await listen("assistant-waiting", () => {
|
||||
document.getElementById("arc-reactor")?.classList.remove("active")
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@@ -1,25 +1,43 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { appInfo } from "@/stores"
|
||||
|
||||
import { tg_official_link, github_repository_link } from "@/stores";
|
||||
let authorName = ""
|
||||
let tgLink = ""
|
||||
let repoLink = ""
|
||||
|
||||
let current_year = new Date().getFullYear();
|
||||
let author_name = "";
|
||||
const currentYear = new Date().getFullYear()
|
||||
|
||||
(async () => {
|
||||
author_name = await invoke("get_author_name")
|
||||
appInfo.subscribe(info => {
|
||||
tgLink = info.tgOfficialLink
|
||||
repoLink = info.repositoryLink
|
||||
})
|
||||
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
onMount(async () => {
|
||||
try {
|
||||
authorName = await invoke<string>("get_author_name")
|
||||
} catch (err) {
|
||||
console.error("failed to get author name:", err)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<footer id="footer">
|
||||
<p>© {current_year}. Автор проекта: {author_name}</p>
|
||||
<p style="margin-top: 5px;margin-bottom: 15px;">
|
||||
<a href="{tg_official_link}" target="_blank" class="special-link"><img src="/media/icons/howdy-logo.png" alt="" width="20px"> Наш телеграм</a> канал.
|
||||
<p>© {currentYear}. Автор проекта: {authorName}</p>
|
||||
<p class="links">
|
||||
<a href={tgLink} target="_blank" class="special-link">
|
||||
<img src="/media/icons/howdy-logo.png" alt="Telegram" width="20px" />
|
||||
Наш телеграм
|
||||
</a>
|
||||
канал.
|
||||
|
||||
<a href="{github_repository_link}" target="_blank"><img src="/media/icons/github-logo.png" alt="" width="18px"> Github репозиторий</a> проекта.</p>
|
||||
<a href={repoLink} target="_blank">
|
||||
<img src="/media/icons/github-logo.png" alt="GitHub" width="18px" />
|
||||
Github репозиторий
|
||||
</a>
|
||||
проекта.
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -34,16 +52,21 @@
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
&.links {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #185876;
|
||||
text-decoration: none;
|
||||
transition: opacity .5s;
|
||||
transition: opacity 0.5s;
|
||||
|
||||
img {
|
||||
opacity: .5;
|
||||
transition: opacity .5s;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.5s;
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
@@ -61,11 +84,9 @@
|
||||
|
||||
&:hover {
|
||||
color: #FF07FC;
|
||||
|
||||
background: url(/media/images/bg/bg24.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { Dashboard, Gear } from 'radix-icons-svelte'
|
||||
import {isActive} from '@roxi/routify'
|
||||
import { isActive } from "@roxi/routify"
|
||||
import { Dashboard, Gear } from "radix-icons-svelte"
|
||||
|
||||
let app_version = "";
|
||||
let appVersion = ""
|
||||
|
||||
(async () => {
|
||||
app_version = await invoke("get_app_version")
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
onMount(async () => {
|
||||
try {
|
||||
appVersion = await invoke<string>("get_app_version")
|
||||
} catch (err) {
|
||||
console.error("failed to get app version:", err)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<header id="header">
|
||||
<div class="logo">
|
||||
<a href="/" title="Проект канала Хауди Хо!"><img src="/media/header-logo.png" alt=""></a>
|
||||
<a href="/" title="Проект канала Хауди Хо!">
|
||||
<img src="/media/header-logo.png" alt="Jarvis Logo" />
|
||||
</a>
|
||||
<div>
|
||||
<h1><a href="/">JARVIS</a></h1>
|
||||
<h2>v{app_version} <small style="color: #8AC832;opacity: .9;font-size: 13px;">BETA</small></h2>
|
||||
<h2>
|
||||
v{appVersion}
|
||||
<small class="beta-badge">BETA</small>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="top-menu">
|
||||
<ul>
|
||||
<li><a href="/commands" class:active={$isActive('/commands')}><Dashboard /> Команды</a></li>
|
||||
<li><a href="/settings" class:active={$isActive('/settings')}><Gear /> Настройки</a></li>
|
||||
<li>
|
||||
<a href="/commands" class:active={$isActive("/commands")}>
|
||||
<Dashboard /> Команды
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/settings" class:active={$isActive("/settings")}>
|
||||
<Gear /> Настройки
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<style lang="scss">
|
||||
.beta-badge {
|
||||
color: #8AC832;
|
||||
opacity: 0.9;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
<nav>
|
||||
<a href="/index">Main Page</a>
|
||||
<a href="/">Main Page</a>
|
||||
<a href="/settings">Настройки</a>
|
||||
</nav>
|
||||
@@ -1,65 +1,54 @@
|
||||
<!-- Based on: https://github.com/rembertdesigns/Iron-Man-Arc-Reactor-Pure-CSS and https://codepen.io/FlyingEmu/pen/DZNqEj -->
|
||||
<!-- Based on: https://github.com/rembertdesigns/Iron-Man-Arc-Reactor-Pure-CSS -->
|
||||
<!-- and https://codepen.io/FlyingEmu/pen/DZNqEj -->
|
||||
|
||||
<div id="arc-reactor" class="reactor-container">
|
||||
<div class="reactor-container-inner circle abs-center">
|
||||
<ul class="marks"><li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li>
|
||||
<li></li><li></li><li></li><li></li><li></li><li></li></ul>
|
||||
<ul class="marks">
|
||||
{#each Array(60) as _, i}
|
||||
<li></li>
|
||||
{/each}
|
||||
</ul>
|
||||
<div class="e7">
|
||||
<div class="semi_arc_3 e5_1">
|
||||
<div class="semi_arc_3 e5_2">
|
||||
<div class="semi_arc_3 e5_3">
|
||||
<div class="semi_arc_3 e5_4" />
|
||||
<div class="semi_arc_3 e5_4"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tunnel circle abs-center" />
|
||||
<div class="core-wrapper circle abs-center" />
|
||||
<div class="core-outer circle abs-center" />
|
||||
<div class="core-inner circle abs-center" />
|
||||
<div class="tunnel circle abs-center"></div>
|
||||
<div class="core-wrapper circle abs-center"></div>
|
||||
<div class="core-outer circle abs-center"></div>
|
||||
<div class="core-inner circle abs-center"></div>
|
||||
<div class="coil-container">
|
||||
<div class="coil coil-1" />
|
||||
<div class="coil coil-2" />
|
||||
<div class="coil coil-3" />
|
||||
<div class="coil coil-4" />
|
||||
<div class="coil coil-5" />
|
||||
<div class="coil coil-6" />
|
||||
<div class="coil coil-7" />
|
||||
<div class="coil coil-8" />
|
||||
{#each Array(8) as _, i}
|
||||
<div class="coil coil-{i + 1}"></div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss" global>
|
||||
$arc_radius: 130px;
|
||||
// [ Variables ]--
|
||||
$arc-radius: 130px;
|
||||
$size3: 6px;
|
||||
$cshadow: rgba(2, 254, 255, 0.8);
|
||||
$marks_color_1: rgba(2, 254, 255, 1);
|
||||
$marks_color_2: rgba(2, 254, 255, 0.3);
|
||||
$marks-color-1: rgba(2, 254, 255, 1);
|
||||
$marks-color-2: rgba(2, 254, 255, 0.3);
|
||||
$colour1: rgba(2, 255, 255, 0.15);
|
||||
$colour3: rgba(2, 255, 255, 0.3);
|
||||
$cshadow: rgba(2, 254, 255, 0.8);
|
||||
|
||||
// [ Base container ]--
|
||||
.reactor-container {
|
||||
width: 300px;
|
||||
height: 320px;
|
||||
margin: auto;
|
||||
// border: 1px dashed #888;
|
||||
position: relative;
|
||||
border-radius: 50%;
|
||||
transition: scale 1s ease, opacity .5s ease;
|
||||
transition: scale 1s ease, opacity 0.5s ease;
|
||||
scale: 0.9;
|
||||
opacity: .9;
|
||||
// background-color: #384c50;
|
||||
// border: 1px solid #121414;
|
||||
// box-shadow: 0px 0px 32px 8px #121414, 0px 0px 4px 1px #121414 inset;
|
||||
opacity: 0.9;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
@@ -67,16 +56,19 @@
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.reactor-container-inner {
|
||||
height: 238px;
|
||||
width: 238px;
|
||||
background-color: #161a1b;
|
||||
box-shadow: 0px 0px 50px 15px $colour3, inset 0px 0px 50px 15px $colour3;
|
||||
// box-shadow: 0px 0px 4px 1px #52fefe;
|
||||
}
|
||||
|
||||
// [ Utility classes ]--
|
||||
.circle {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.abs-center {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -85,6 +77,8 @@
|
||||
left: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
// [ Core elements ]--
|
||||
.core-inner {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
@@ -92,6 +86,7 @@
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 7px 5px #52fefe, 0px 0px 10px 10px #52fefe inset;
|
||||
}
|
||||
|
||||
.core-outer {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
@@ -99,18 +94,22 @@
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 2px 1px #52fefe, 0px 0px 10px 5px #52fefe inset;
|
||||
}
|
||||
|
||||
.core-wrapper {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
background-color: #073c4b;
|
||||
box-shadow: 0px 0px 5px 4px #52fefe, 0px 0px 6px 2px #52fefe inset;
|
||||
}
|
||||
|
||||
.tunnel {
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 5px 1px #52fefe, 0px 0px 5px 4px #52fefe inset;
|
||||
}
|
||||
|
||||
// [ Coil animation ]--
|
||||
.coil-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
@@ -118,6 +117,7 @@
|
||||
animation: 10s infinite linear reactor-anim;
|
||||
transition: animation 1s;
|
||||
}
|
||||
|
||||
.coil {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
@@ -128,43 +128,19 @@
|
||||
background-color: #073c4b;
|
||||
box-shadow: 0px 0px 5px #52fefe inset;
|
||||
}
|
||||
.coil-1 {
|
||||
transform: rotate(0deg);
|
||||
|
||||
@for $i from 1 through 8 {
|
||||
.coil-#{$i} {
|
||||
transform: rotate(#{($i - 1) * 45}deg);
|
||||
}
|
||||
.coil-2 {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.coil-3 {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.coil-4 {
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
.coil-5 {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.coil-6 {
|
||||
transform: rotate(225deg);
|
||||
}
|
||||
.coil-7 {
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
.coil-8 {
|
||||
transform: rotate(315deg);
|
||||
}
|
||||
|
||||
@keyframes reactor-anim {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin border-radius($pixel...) {
|
||||
border-radius: $pixel;
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
// [ Arc element ]--
|
||||
.e7 {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
@@ -177,66 +153,11 @@
|
||||
margin: auto;
|
||||
border: $size3 solid transparent;
|
||||
background: transparent;
|
||||
@include border-radius(50%);
|
||||
transform: rotateZ(0deg);
|
||||
transition: box-shadow 3s ease;
|
||||
text-align: center;
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
.semi_arc {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 6px solid #02feff;
|
||||
background: rgba(2, 254, 255, 0.2);
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
transform: rotateZ(0deg);
|
||||
transition: box-shadow 3s ease;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.semi_arc:hover {
|
||||
box-shadow: 0px 0px 30px $cshadow;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.semi_arc_2 {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 94%;
|
||||
height: 94%;
|
||||
left: 3%;
|
||||
top: 3%;
|
||||
border: 5px solid #02feff;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
animation: rotate 4s linear infinite;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.semi_arc_2:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 94%;
|
||||
height: 94%;
|
||||
left: 3%;
|
||||
top: 3%;
|
||||
border: 4px solid #02feff;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
animation: rotate_anti 2s linear infinite;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.semi_arc_3 {
|
||||
@@ -247,132 +168,27 @@
|
||||
left: 3%;
|
||||
top: 3%;
|
||||
border: 5px solid #02feff;
|
||||
-moz-border-radius: 50%;
|
||||
-webkit-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
animation: rotate 4s linear infinite;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.e1:after {
|
||||
border-color: rgba(2, 255, 255, 0.6);
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
|
||||
.e2:after {
|
||||
border-color: rgba(2, 255, 255, 0.6);
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-bottom: 5px solid transparent;
|
||||
}
|
||||
|
||||
.e3 {
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
animation: rotate 5s linear infinite;
|
||||
}
|
||||
|
||||
.e3:after {
|
||||
border-color: rgba(2, 255, 255, 0.6);
|
||||
border-top: 5px solid transparent;
|
||||
border-bottom: 5px solid transparent;
|
||||
}
|
||||
|
||||
.e4 {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.e4_1 {
|
||||
border-color: rgba(2, 255, 255, 0.3);
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
|
||||
.e4_1:after {
|
||||
border-color: rgba(2, 255, 255, 0.6);
|
||||
border-top: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
}
|
||||
|
||||
.e5 {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.e5_1 {
|
||||
color: rgba(2, 255, 255, 0.15);
|
||||
border: 2px solid;
|
||||
border-left: 2px solid transparent;
|
||||
animation: rotate 5s linear infinite;
|
||||
}
|
||||
|
||||
.e5_2 {
|
||||
color: rgba(2, 255, 255, 0.7);
|
||||
border: 4px solid;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
animation: rotate_anti 4s linear infinite;
|
||||
}
|
||||
|
||||
.e5_3 {
|
||||
color: rgba(2, 255, 255, 0.5);
|
||||
border: 2px solid;
|
||||
border-left: 2px solid transparent;
|
||||
border-right: 2px solid transparent;
|
||||
animation: rotate 3s linear infinite;
|
||||
}
|
||||
|
||||
.e5_4 {
|
||||
color: rgba(2, 255, 255, 0.15);
|
||||
border: 4px solid;
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-bottom: 4px solid transparent;
|
||||
animation: rotate_anti 2s linear infinite;
|
||||
}
|
||||
|
||||
.e6 {
|
||||
border-color: transparent;
|
||||
background: rgba(255, 255, 255, 0);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
@keyframes rotate {
|
||||
0% { transform: rotateZ(0deg); }
|
||||
100% { transform: rotateZ(360deg); }
|
||||
}
|
||||
|
||||
@keyframes rotate_anti {
|
||||
0% {
|
||||
transform: rotateZ(360deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotateZ(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(360deg);
|
||||
}
|
||||
0% { transform: rotateZ(0deg); }
|
||||
100% { transform: rotateZ(-360deg); }
|
||||
}
|
||||
|
||||
// [ Marks ]--
|
||||
.marks {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
|
||||
li {
|
||||
display: block;
|
||||
width: 3px;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
background: $cshadow;
|
||||
position: absolute;
|
||||
@@ -383,213 +199,23 @@
|
||||
}
|
||||
|
||||
@keyframes colour_ease2 {
|
||||
0% {
|
||||
background: $marks_color_1;
|
||||
0% { background: $marks-color-1; }
|
||||
50% { background: $marks-color-2; }
|
||||
100% { background: $marks-color-1; }
|
||||
}
|
||||
50% {
|
||||
background: $marks_color_2;
|
||||
}
|
||||
100% {
|
||||
background: $marks_color_1;
|
||||
|
||||
// generate mark rotations
|
||||
@for $i from 1 through 60 {
|
||||
.marks li:nth-child(#{$i}) {
|
||||
transform: rotate(#{$i * 6}deg) translateY($arc-radius);
|
||||
}
|
||||
}
|
||||
|
||||
.marks li:first-child {
|
||||
transform: rotate(6deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(2) {
|
||||
transform: rotate(12deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(3) {
|
||||
transform: rotate(18deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(4) {
|
||||
transform: rotate(24deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(5) {
|
||||
transform: rotate(30deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(6) {
|
||||
transform: rotate(36deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(7) {
|
||||
transform: rotate(42deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(8) {
|
||||
transform: rotate(48deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(9) {
|
||||
transform: rotate(54deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(10) {
|
||||
transform: rotate(60deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(11) {
|
||||
transform: rotate(66deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(12) {
|
||||
transform: rotate(72deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(13) {
|
||||
transform: rotate(78deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(14) {
|
||||
transform: rotate(84deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(15) {
|
||||
transform: rotate(90deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(16) {
|
||||
transform: rotate(96deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(17) {
|
||||
transform: rotate(102deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(18) {
|
||||
transform: rotate(108deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(19) {
|
||||
transform: rotate(114deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(20) {
|
||||
transform: rotate(120deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(21) {
|
||||
transform: rotate(126deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(22) {
|
||||
transform: rotate(132deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(23) {
|
||||
transform: rotate(138deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(24) {
|
||||
transform: rotate(144deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(25) {
|
||||
transform: rotate(150deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(26) {
|
||||
transform: rotate(156deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(27) {
|
||||
transform: rotate(162deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(28) {
|
||||
transform: rotate(168deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(29) {
|
||||
transform: rotate(174deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(30) {
|
||||
transform: rotate(180deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(31) {
|
||||
transform: rotate(186deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(32) {
|
||||
transform: rotate(192deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(33) {
|
||||
transform: rotate(198deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(34) {
|
||||
transform: rotate(204deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(35) {
|
||||
transform: rotate(210deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(36) {
|
||||
transform: rotate(216deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(37) {
|
||||
transform: rotate(222deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(38) {
|
||||
transform: rotate(228deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(39) {
|
||||
transform: rotate(234deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(40) {
|
||||
transform: rotate(240deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(41) {
|
||||
transform: rotate(246deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(42) {
|
||||
transform: rotate(252deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(43) {
|
||||
transform: rotate(258deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(44) {
|
||||
transform: rotate(264deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(45) {
|
||||
transform: rotate(270deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(46) {
|
||||
transform: rotate(276deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(47) {
|
||||
transform: rotate(282deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(48) {
|
||||
transform: rotate(288deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(49) {
|
||||
transform: rotate(294deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(50) {
|
||||
transform: rotate(300deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(51) {
|
||||
transform: rotate(306deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(52) {
|
||||
transform: rotate(312deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(53) {
|
||||
transform: rotate(318deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(54) {
|
||||
transform: rotate(324deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(55) {
|
||||
transform: rotate(330deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(56) {
|
||||
transform: rotate(336deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(57) {
|
||||
transform: rotate(342deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(58) {
|
||||
transform: rotate(348deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(59) {
|
||||
transform: rotate(354deg) translateY($arc_radius);
|
||||
}
|
||||
.marks li:nth-child(60) {
|
||||
transform: rotate(360deg) translateY($arc_radius);
|
||||
}
|
||||
|
||||
/*
|
||||
Some overrides.
|
||||
*/
|
||||
// [ Active state ]--
|
||||
.reactor-container.active {
|
||||
$arc_radius: 130px;
|
||||
$size3: 6px;
|
||||
$cshadow: rgba(2, 254, 255, 0.8);
|
||||
$marks_color_1: rgba(2, 254, 255, 1);
|
||||
$marks_color_2: rgba(2, 254, 255, 0.3);
|
||||
$colour1: rgba(2, 255, 255, 0.15);
|
||||
$colour3: rgba(2, 255, 255, 0.3);
|
||||
$cshadow: rgba(2, 254, 255, 0.8);
|
||||
|
||||
scale: 1.1;
|
||||
opacity: 1;
|
||||
|
||||
.coil-container {
|
||||
animation: 3s infinite linear reactor-anim;
|
||||
}
|
||||
@@ -598,50 +224,9 @@
|
||||
box-shadow: 0px 0px 50px 15px $colour3, inset 0px 0px 50px 15px $colour3;
|
||||
}
|
||||
|
||||
.core-inner {
|
||||
border: 5px solid #1b4e5f;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 7px 5px #52fefe, 0px 0px 10px 10px #52fefe inset;
|
||||
.e5_1 { animation: rotate 3s linear infinite; }
|
||||
.e5_2 { animation: rotate_anti 2s linear infinite; }
|
||||
.e5_3 { animation: rotate 2s linear infinite; }
|
||||
.e5_4 { animation: rotate_anti 2s linear infinite; }
|
||||
}
|
||||
|
||||
.core-outer {
|
||||
border: 1px solid #52fefe;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 2px 1px #52fefe, 0px 0px 10px 5px #52fefe inset;
|
||||
}
|
||||
.core-wrapper {
|
||||
background-color: #073c4b;
|
||||
box-shadow: 0px 0px 5px 4px #52fefe, 0px 0px 6px 2px #52fefe inset;
|
||||
}
|
||||
.tunnel {
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0px 0px 5px 1px #52fefe, 0px 0px 5px 4px #52fefe inset;
|
||||
}
|
||||
.coil {
|
||||
background-color: #073c4b;
|
||||
box-shadow: 0px 0px 5px #52fefe inset;
|
||||
}
|
||||
|
||||
.semi_arc {
|
||||
border: 6px solid #02feff;
|
||||
background: rgba(2, 254, 255, 0.2);
|
||||
}
|
||||
|
||||
|
||||
.e5_1 {
|
||||
animation: rotate 3s linear infinite;
|
||||
}
|
||||
|
||||
.e5_2 {
|
||||
animation: rotate_anti 2s linear infinite;
|
||||
}
|
||||
|
||||
.e5_3 {
|
||||
animation: rotate 2s linear infinite;
|
||||
}
|
||||
|
||||
.e5_4 {
|
||||
animation: rotate_anti 2s linear infinite;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,14 +1,14 @@
|
||||
<script>
|
||||
export let no_margin = false;
|
||||
<script lang="ts">
|
||||
export let noMargin = false
|
||||
</script>
|
||||
|
||||
<div class="h-divider" class:no-margin="{no_margin}"></div>
|
||||
<div class="h-divider" class:no-margin={noMargin}></div>
|
||||
|
||||
<style lang="scss">
|
||||
.h-divider {
|
||||
margin: 20px 0;
|
||||
height: 40px;
|
||||
background-image: url(media/images/decor.png);
|
||||
background-image: url(/media/images/decor.png);
|
||||
background-position: center;
|
||||
|
||||
&.no-margin {
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
<script>
|
||||
let search_q = "";
|
||||
<script lang="ts">
|
||||
let searchQuery = ""
|
||||
</script>
|
||||
|
||||
<div id="search-form" class="search" class:active={search_q != ""}>
|
||||
<div id="search-form" class="search" class:active={searchQuery !== ""}>
|
||||
<form action="#" method="GET">
|
||||
<input bind:value={search_q} type="text" name="q" placeholder="Введите команду или скажите «Джарвис» ..." autocomplete="off" minlength="3" maxlength="30">
|
||||
<button type="submit"></button>
|
||||
<input
|
||||
bind:value={searchQuery}
|
||||
type="text"
|
||||
name="q"
|
||||
placeholder="Введите команду или скажите «Джарвис» ..."
|
||||
autocomplete="off"
|
||||
minlength="3"
|
||||
maxlength="30"
|
||||
/>
|
||||
<button type="submit" aria-label="Search"></button>
|
||||
<small>Enter</small>
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,46 +1,46 @@
|
||||
<script>
|
||||
// IMPORTS
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { onMount } from 'svelte'
|
||||
import { capitalizeFirstLetter } from "@/functions";
|
||||
import { capitalizeFirstLetter } from "@/functions"
|
||||
|
||||
// VARIABLES
|
||||
let selected_microphone = 0;
|
||||
let microphone_label = "";
|
||||
let microphoneLabel = ""
|
||||
let wakeWordEngine = ""
|
||||
let sttEngine = "Vosk"
|
||||
let ramUsage = "-"
|
||||
|
||||
let nn_details = {
|
||||
"ww_engine": "",
|
||||
"stt_engine": "Vosk"
|
||||
let interval: number | null = null
|
||||
|
||||
async function updateRamUsage() {
|
||||
try {
|
||||
const usage = await invoke<number>("get_current_ram_usage")
|
||||
ramUsage = usage.toFixed(2)
|
||||
} catch (err) {
|
||||
console.error("failed to get ram usage:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// let resources_cpu_temp = 0;
|
||||
// let resources_cpu_usage = 0;
|
||||
let resources_ram_usage = "-";
|
||||
|
||||
// CODE
|
||||
setInterval(() => {
|
||||
(async () => {
|
||||
resources_ram_usage = Number(await invoke("get_current_ram_usage")).toFixed(2);
|
||||
// resources_cpu_temp = await invoke("get_cpu_temp");
|
||||
// resources_cpu_usage = +Number(await invoke("get_cpu_usage")).toFixed(2);
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
onMount(async () => {
|
||||
(async () => {
|
||||
selected_microphone = +Number(await invoke("db_read", {key: "selected_microphone"}));
|
||||
microphone_label = await invoke("pv_get_audio_device_name", {idx: selected_microphone});
|
||||
// start polling ram usage
|
||||
interval = setInterval(updateRamUsage, 1000) as unknown as number
|
||||
|
||||
nn_details["ww_engine"] = capitalizeFirstLetter(await invoke("db_read", {key: "selected_wake_word_engine"}));
|
||||
try {
|
||||
// load microphone info
|
||||
const micIndex = Number(await invoke<string>("db_read", { key: "selected_microphone" }))
|
||||
microphoneLabel = await invoke<string>("pv_get_audio_device_name", { idx: micIndex })
|
||||
|
||||
// resources_cpu_temp = await invoke("get_cpu_temp");
|
||||
// resources_cpu_usage = +Number(await invoke("get_cpu_usage")).toFixed(2);
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
// load wake word engine
|
||||
const engine = await invoke<string>("db_read", { key: "selected_wake_word_engine" })
|
||||
wakeWordEngine = capitalizeFirstLetter(engine)
|
||||
} catch (err) {
|
||||
console.error("failed to load stats:", err)
|
||||
}
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
if (interval) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="statistics">
|
||||
@@ -48,21 +48,23 @@
|
||||
<div class="pulse"><div class="wave"></div></div>
|
||||
<div class="info">
|
||||
<span class="num">Микрофон</span>
|
||||
<small title="{microphone_label}">{microphone_label}</small>
|
||||
<small title={microphoneLabel}>{microphoneLabel}</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="files">
|
||||
<div class="pulse"><div class="wave"></div></div>
|
||||
<div class="info">
|
||||
<span class="num">Нейросети</span>
|
||||
<small>{nn_details["ww_engine"]} + {nn_details["stt_engine"]}</small>
|
||||
<small>{wakeWordEngine} + {sttEngine}</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="downloads hint--bottom" aria-label="Общее количество скачиваний по всему проекту">
|
||||
<div class="pulse"><div class="wave"></div></div>
|
||||
<div class="info">
|
||||
<span class="num">Ресурсы</span>
|
||||
<small><!-- CPU {resources_cpu_usage}%<br /> -->RAM {resources_ram_usage}mb</small>
|
||||
<small>RAM {ramUsage}mb</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -84,6 +86,7 @@
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
// [ Online/Microphone stat ]--
|
||||
& > .online {
|
||||
position: relative;
|
||||
width: 40%;
|
||||
@@ -93,24 +96,22 @@
|
||||
$end-color: rgba(0, 191, 8, 0);
|
||||
|
||||
& > .pulse::before {
|
||||
background-color: rgba(0, 191, 8, 1);
|
||||
background-color: $base-color;
|
||||
}
|
||||
|
||||
& > .pulse::after {
|
||||
background-color: rgba(0, 191, 8, 1);
|
||||
animation: online-cdot linear 3s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-fill-mode: forwards;
|
||||
background-color: $base-color;
|
||||
animation: online-cdot linear 3s infinite forwards;
|
||||
}
|
||||
|
||||
& > .pulse .wave {
|
||||
background-color: rgba(0, 191, 8, 0.4);
|
||||
animation: online-radarWave cubic-bezier(0, 0.54, 0.53, 1) 3s 0s;
|
||||
animation-iteration-count: infinite;
|
||||
background-color: $mid-color;
|
||||
animation: online-radarWave cubic-bezier(0, 0.54, 0.53, 1) 3s 0s infinite;
|
||||
}
|
||||
|
||||
& > .pulse .wave::after {
|
||||
background-color: rgba(0, 191, 8, 0.4);
|
||||
animation: online-radarWave cubic-bezier(0, 0.54, 0.53, 1) 3s
|
||||
0.1s;
|
||||
animation-iteration-count: infinite;
|
||||
background-color: $mid-color;
|
||||
animation: online-radarWave cubic-bezier(0, 0.54, 0.53, 1) 3s 0.1s infinite;
|
||||
}
|
||||
|
||||
& > .info {
|
||||
@@ -123,6 +124,7 @@
|
||||
font-weight: bold;
|
||||
color: #00bf08;
|
||||
}
|
||||
|
||||
& > small {
|
||||
display: block;
|
||||
color: #535a60;
|
||||
@@ -137,34 +139,19 @@
|
||||
}
|
||||
|
||||
@keyframes online-cdot {
|
||||
0% {
|
||||
opacity: 0.3;
|
||||
background: $base-color;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
background: $end-color;
|
||||
}
|
||||
0% { opacity: 0.3; background: $base-color; }
|
||||
50% { opacity: 0.5; }
|
||||
100% { opacity: 1; background: $end-color; }
|
||||
}
|
||||
|
||||
@keyframes online-radarWave {
|
||||
0% {
|
||||
opacity: 0.1;
|
||||
transform: scale(0);
|
||||
}
|
||||
5% {
|
||||
background: $mid-color;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.2);
|
||||
background: $end-color;
|
||||
}
|
||||
0% { opacity: 0.1; transform: scale(0); }
|
||||
5% { background: $mid-color; opacity: 1; }
|
||||
100% { transform: scale(1.2); background: $end-color; }
|
||||
}
|
||||
}
|
||||
|
||||
// [ Files/Neural networks stat ]--
|
||||
& > .files {
|
||||
position: relative;
|
||||
width: 35%;
|
||||
@@ -176,22 +163,20 @@
|
||||
& > .pulse::before {
|
||||
background-color: $base-color;
|
||||
}
|
||||
|
||||
& > .pulse::after {
|
||||
background-color: $base-color;
|
||||
animation: files-cdot linear 5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-fill-mode: forwards;
|
||||
animation: files-cdot linear 5s infinite forwards;
|
||||
}
|
||||
|
||||
& > .pulse .wave {
|
||||
background-color: $mid-color;
|
||||
animation: files-radarWave cubic-bezier(0, 0.54, 0.53, 1) 5s 0s;
|
||||
animation-iteration-count: infinite;
|
||||
animation: files-radarWave cubic-bezier(0, 0.54, 0.53, 1) 5s 0s infinite;
|
||||
}
|
||||
|
||||
& > .pulse .wave::after {
|
||||
background-color: $mid-color;
|
||||
animation: files-radarWave cubic-bezier(0, 0.54, 0.53, 1) 5s
|
||||
0.1s;
|
||||
animation-iteration-count: infinite;
|
||||
animation: files-radarWave cubic-bezier(0, 0.54, 0.53, 1) 5s 0.1s infinite;
|
||||
}
|
||||
|
||||
& > .info {
|
||||
@@ -204,6 +189,7 @@
|
||||
font-weight: bold;
|
||||
color: #ff8130;
|
||||
}
|
||||
|
||||
& > small {
|
||||
display: block;
|
||||
color: #535a60;
|
||||
@@ -214,64 +200,45 @@
|
||||
}
|
||||
|
||||
@keyframes files-cdot {
|
||||
0% {
|
||||
opacity: 0.3;
|
||||
background: $base-color;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
background: $end-color;
|
||||
}
|
||||
0% { opacity: 0.3; background: $base-color; }
|
||||
50% { opacity: 0.5; }
|
||||
100% { opacity: 1; background: $end-color; }
|
||||
}
|
||||
|
||||
@keyframes files-radarWave {
|
||||
0% {
|
||||
opacity: 0.1;
|
||||
transform: scale(0);
|
||||
}
|
||||
5% {
|
||||
background: $mid-color;
|
||||
transform: scale(0.2);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(0.8);
|
||||
background: $end-color;
|
||||
}
|
||||
0% { opacity: 0.1; transform: scale(0); }
|
||||
5% { background: $mid-color; transform: scale(0.2); opacity: 1; }
|
||||
100% { transform: scale(0.8); background: $end-color; }
|
||||
}
|
||||
}
|
||||
|
||||
// [ Downloads/Resources stat ]--
|
||||
& > .downloads {
|
||||
position: relative;
|
||||
|
||||
$base-color: rgba(11,66,166, 1);
|
||||
$base-color: rgba(11, 66, 166, 1);
|
||||
$mid-color: rgba(32, 150, 243, 0.4);
|
||||
$end-color: rgba(32, 150, 243, 0);
|
||||
|
||||
& > .pulse::before {
|
||||
background: rgba(32, 150, 243, 1);
|
||||
}
|
||||
|
||||
& > .pulse::after {
|
||||
background: rgba(32, 150, 243, 1);
|
||||
animation: downloads-cdot linear 7s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-fill-mode: forwards;
|
||||
animation: downloads-cdot linear 7s infinite forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
& > .pulse .wave {
|
||||
background-color: $mid-color;
|
||||
animation: downloads-radarWave cubic-bezier(0, 0.54, 0.53, 1) 7s
|
||||
0s;
|
||||
animation-iteration-count: infinite;
|
||||
animation: downloads-radarWave cubic-bezier(0, 0.54, 0.53, 1) 7s 0s infinite;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
& > .pulse .wave::after {
|
||||
background-color: $mid-color;
|
||||
animation: downloads-radarWave cubic-bezier(0, 0.54, 0.53, 1) 7s
|
||||
0.1s;
|
||||
animation-iteration-count: infinite;
|
||||
animation: downloads-radarWave cubic-bezier(0, 0.54, 0.53, 1) 7s 0.1s infinite;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
@@ -296,34 +263,19 @@
|
||||
}
|
||||
|
||||
@keyframes downloads-cdot {
|
||||
0% {
|
||||
opacity: 0.3;
|
||||
background: $base-color;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
background: $end-color;
|
||||
}
|
||||
0% { opacity: 0.3; background: $base-color; }
|
||||
50% { opacity: 0.5; }
|
||||
100% { opacity: 1; background: $end-color; }
|
||||
}
|
||||
|
||||
@keyframes downloads-radarWave {
|
||||
0% {
|
||||
opacity: 0.1;
|
||||
transform: scale(0);
|
||||
}
|
||||
5% {
|
||||
background: $mid-color;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(0.7);
|
||||
background: $end-color;
|
||||
}
|
||||
0% { opacity: 0.1; transform: scale(0); }
|
||||
5% { background: $mid-color; opacity: 1; }
|
||||
100% { transform: scale(0.7); background: $end-color; }
|
||||
}
|
||||
}
|
||||
|
||||
// [ Shared pulse styles ]--
|
||||
.pulse {
|
||||
position: relative;
|
||||
height: 100px;
|
||||
@@ -333,8 +285,9 @@
|
||||
top: 0px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.pulse::before {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
@@ -342,10 +295,11 @@
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
opacity: .5;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.pulse::after {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
@@ -354,6 +308,7 @@
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.pulse .wave {
|
||||
position: absolute;
|
||||
left: 7%;
|
||||
@@ -363,8 +318,9 @@
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.pulse .wave::after {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 7%;
|
||||
top: 7%;
|
||||
|
||||
@@ -1,38 +1,40 @@
|
||||
// ### FONTS
|
||||
$prim-font: "Roboto", sans-serif;
|
||||
$sec-font: "Roboto Condensed", sans-serif;
|
||||
|
||||
html, body {
|
||||
// ### BASE
|
||||
html,
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
// ### SCROLLBAR
|
||||
::-webkit-scrollbar {
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: -webkit-gradient(linear,left top,left bottom,from(#999),to(#27292F));
|
||||
background: linear-gradient(to bottom,#999,#27292F);
|
||||
background: linear-gradient(to bottom, #999, #27292f);
|
||||
}
|
||||
|
||||
// ### TEXT SELECTION
|
||||
::selection {
|
||||
background: #FF8901!important; /* WebKit/Blink Browsers */
|
||||
color: white!important;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, .5)!important;
|
||||
background: #ff8901 !important;
|
||||
color: white !important;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background: #FF8901!important; /* WebKit/Blink Browsers */
|
||||
color: white!important;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, .5)!important;
|
||||
background: #ff8901 !important;
|
||||
color: white !important;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
/*
|
||||
* HEADER
|
||||
*/
|
||||
|
||||
// ### HEADER
|
||||
#header {
|
||||
height: 80px;
|
||||
background-color: #0c1013;
|
||||
@@ -40,7 +42,6 @@ html, body {
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
text-align: justify;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -50,10 +51,10 @@ html, body {
|
||||
& > a > img {
|
||||
width: 57px;
|
||||
display: inline-block;
|
||||
transition: .5s opacity ease-in;
|
||||
transition: 0.5s opacity ease-in;
|
||||
|
||||
&:hover {
|
||||
opacity: .8;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,11 +76,11 @@ html, body {
|
||||
|
||||
& > a {
|
||||
color: white;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, .5);
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #8AC832;
|
||||
color: #8ac832;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +90,6 @@ html, body {
|
||||
font-family: $sec-font;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.1px;
|
||||
margin-top: 2px;
|
||||
letter-spacing: -0.01px;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ html, body {
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
transition: .2s color;
|
||||
transition: 0.2s color;
|
||||
padding: 10px 0;
|
||||
|
||||
& > svg {
|
||||
@@ -133,15 +133,12 @@ html, body {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
&:hover, &.active {
|
||||
color: #8AC832;
|
||||
&:hover,
|
||||
&.active {
|
||||
color: #8ac832;
|
||||
|
||||
&:after {
|
||||
-webkit-transform: scaleX(1);
|
||||
-ms-transform: scaleX(1);
|
||||
transform: scaleX(1);
|
||||
-webkit-transform-origin: left;
|
||||
-ms-transform-origin: left;
|
||||
transform-origin: left;
|
||||
}
|
||||
}
|
||||
@@ -151,29 +148,24 @@ html, body {
|
||||
display: block;
|
||||
height: 3px;
|
||||
border-radius: 10px;
|
||||
-webkit-transform: scaleX(0);
|
||||
-ms-transform: scaleX(0);
|
||||
transform: scaleX(0);
|
||||
transition: .4s -webkit-transform;
|
||||
transition: .4s transform;
|
||||
-webkit-transform-origin: 100% 0;
|
||||
-ms-transform-origin: 100% 0;
|
||||
transition: 0.4s transform;
|
||||
transform-origin: 100% 0;
|
||||
background: #8AC832;
|
||||
opacity: 0.90;
|
||||
background: #8ac832;
|
||||
opacity: 0.9;
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 333;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ### SEARCH BAR
|
||||
.search {
|
||||
display: block;
|
||||
margin: 20px 0;
|
||||
@@ -189,15 +181,13 @@ html, body {
|
||||
border: 1px solid rgba(6, 6, 6, 0.99);
|
||||
background-color: #0f1012;
|
||||
outline: none;
|
||||
|
||||
color: #D1D1D1;
|
||||
color: #d1d1d1;
|
||||
font-family: $sec-font;
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
line-height: 70.58px;
|
||||
padding-left: 20px;
|
||||
padding-right: 45px;
|
||||
padding-right: 45px;
|
||||
|
||||
&::placeholder {
|
||||
color: #676767;
|
||||
@@ -205,7 +195,7 @@ html, body {
|
||||
}
|
||||
|
||||
&:focus + button + small {
|
||||
opacity: .3;
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +210,7 @@ html, body {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
opacity: 1;
|
||||
transition: .3s opacity;
|
||||
transition: 0.3s opacity;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
@@ -233,14 +223,12 @@ html, body {
|
||||
background-repeat: no-repeat;
|
||||
background-size: 75%;
|
||||
background-position: center center;
|
||||
transition: all .3s;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::before {
|
||||
&:hover::before {
|
||||
cursor: pointer;
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAbCAYAAABvCO8sAAABN2lDQ1BBZG9iZSBSR0IgKDE5OTgpAAAokZWPv0rDUBSHvxtFxaFWCOLgcCdRUGzVwYxJW4ogWKtDkq1JQ5ViEm6uf/oQjm4dXNx9AidHwUHxCXwDxamDQ4QMBYvf9J3fORzOAaNi152GUYbzWKt205Gu58vZF2aYAoBOmKV2q3UAECdxxBjf7wiA10277jTG+38yH6ZKAyNguxtlIYgK0L/SqQYxBMygn2oQD4CpTto1EE9AqZf7G1AKcv8ASsr1fBBfgNlzPR+MOcAMcl8BTB1da4Bakg7UWe9Uy6plWdLuJkEkjweZjs4zuR+HiUoT1dFRF8jvA2AxH2w3HblWtay99X/+PRHX82Vun0cIQCw9F1lBeKEuf1UYO5PrYsdwGQ7vYXpUZLs3cLcBC7dFtlqF8hY8Dn8AwMZP/fNTP8gAAAAJcEhZcwAACxMAAAsTAQCanBgAAAXRaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0MiA3OS4xNjA5MjQsIDIwMTcvMDcvMTMtMDE6MDY6MzkgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjMtMDQtMjNUMDQ6MzE6NTgrMDU6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIzLTA0LTIzVDA0OjM0OjI3KzA1OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIzLTA0LTIzVDA0OjM0OjI3KzA1OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowZDA5NTdiMi0zYmM3LTcxNDItODcyNS01ODA3MjA2NTFlYTIiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDoxM2UwZWYxNi03OGM0LTE2NGMtODc1Mi0xYjY5OTQ1OTczMGMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5YjNkZTI4Yy1iOTBmLTNjNDUtYjAwNS1kNTExOTE3ZDhkNzIiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjliM2RlMjhjLWI5MGYtM2M0NS1iMDA1LWQ1MTE5MTdkOGQ3MiIgc3RFdnQ6d2hlbj0iMjAyMy0wNC0yM1QwNDozMTo1OCswNTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowZDA5NTdiMi0zYmM3LTcxNDItODcyNS01ODA3MjA2NTFlYTIiIHN0RXZ0OndoZW49IjIwMjMtMDQtMjNUMDQ6MzQ6MjcrMDU6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Wh528AAAC7UlEQVRIiaXWX4gXVRTA8c9v2jLJ6A8ERVAJbUakTr2YqRFl0QRRRk89FBGYqNDLUgY51PQiRERJWhhLQY8RtA+OFm2mGf2RGqEQDAvyoaigrKhNk+3h3mGnX7/9zbgeGO45555zvvfCvWdub/POpTrI6vilGMVF6OEnHMEXmCyyaldboV4LcCPWYnGXVeEQdhRZ9fypApdhG65v+D7GPhwWdjYt7HQUK7GiEfslNhRZtbcL8EG81rDH8TI+G7SyIqtAXqYp1uGRxvT6Iqu2N+OTvvyHG7DvcEv0DYT1gasiq9YJO/06urflZbpxNuAyvBr1z7EE77eBBoA/irn7o2trXqar+4Ej2Bn177Ecx04V1oBOYZVwgmEiL9N5TeATuDDqGY7PFdaATuP2aM7HMzXwTDweJ8ZxcEids4VT2RX6DV6K5lhepgsSrME50flUS41VwrUY9/8DN5vUNXu4P8Fd0XEAR1uS58XxIeGSr2yjFVn1MyajeWeCa6MxOTjlP3KioV+FfXmZFh3y9sRxUYLLonFkcGyrbM7LdH9eptcNianv5SUJFkTjtzkC4UZ8MGS+vmLzE/wZjXNPA3gI9w2Zr2tPjQgt7HwsnCNse5FV61tirozjDwm+isbNHYqf0dB/xD0dYHBTHA8nZlraclzckjgdxwkswtttpLxMzzPTcXYleBN/R8eTLfkf4gbcjV/bYI2avai/kWAKz0XHhrjy2eR3fNIRJC/TSzEWza1FVh2r29PT+CPqu7sW7CDvxPGk2K9r4HEzLe5y7MVZp0PKy3Q3ronmvUVW/UX4D9ayB4/iBaFJH8QDOvzt+0BL8LrwwoNNRVZN1PMjffEv4h/hl3I1Po0LeEW43MNAo8ILb6zhfqzIqmebcbO92m6N0OYBelc4pYNebStwRyP2W+HVVvYX7t9hLe8JO9wUV70Qt8VvmBzFDmwpsurEoIDZgLVsid8aYddLcQUuEO7WL0JrrIQH11tFVp0cVvBfVZDA+HDoxOQAAAAASUVORK5CYII=");
|
||||
}
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAbCAYAAABvCO8sAAABN2lDQ1BBZG9iZSBSR0IgKDE5OTgpAAAokZWPv0rDUBSHvxtFxaFWCOLgcCdRUGzVwYxJW4ogWKtDkq1JQ5ViEm6uf/oQjm4dXNx9AidHwUHxCXwDxamDQ4QMBYvf9J3fORzOAaNi152GUYbzWKt205Gu58vZF2aYAoBOmKV2q3UAECdxxBjf7wiA10277jTG+38yH6ZKAyNguxtlIYgK0L/SqQYxBMygn2oQD4CpTto1EE9AqZf7G1AKcv8ASsr1fBBfgNlzPR+MOcAMcl8BTB1da4Bakg7UWe9Uy6plWdLuJkEkjweZjs4zuR+HiUoT1dFRF8jvA2AxH2w3HblWtay99X/+PRHX82Vun0cIQCw9F1lBeKEuf1UYO5PrYsdwGQ7vYXpUZLs3cLcBC7dFtlqF8hY8Dn8AwMZP/fNTP8gAAAAJcEhZcwAACxMAAAsTAQCanBgAAAXRaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzE0MiA3OS4xNjA5MjQsIDIwMTcvMDcvMTMtMDE6MDY6MzkgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjMtMDQtMjNUMDQ6MzE6NTgrMDU6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIzLTA0LTIzVDA0OjM0OjI3KzA1OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIzLTA0LTIzVDA0OjM0OjI3KzA1OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowZDA5NTdiMi0zYmM3LTcxNDItODcyNS01ODA3MjA2NTFlYTIiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDoxM2UwZWYxNi03OGM0LTE2NGMtODc1Mi0xYjY5OTQ1OTczMGMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5YjNkZTI4Yy1iOTBmLTNjNDUtYjAwNS1kNTExOTE3ZDhkNzIiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjliM2RlMjhjLWI5MGYtM2M0NS1iMDA1LWQ1MTE5MTdkOGQ3MiIgc3RFdnQ6d2hlbj0iMjAyMy0wNC0yM1QwNDozMTo1OCswNTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowZDA5NTdiMi0zYmM3LTcxNDItODcyNS01ODA3MjA2NTFlYTIiIHN0RXZ0OndoZW49IjIwMjMtMDQtMjNUMDQ6MzQ6MjcrMDU6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Wh528AAAC7UlEQVRIiaXWX4gXVRTA8c9v2jLJ6A8ERVAJbUakTr2YqRFl0QRRRk89FBGYqNDLUgY51PQiRERJWhhLQY8RtA+OFm2mGf2RGqEQDAvyoaigrKhNk+3h3mGnX7/9zbgeGO45585zvvfCvWdub/POpTrI6vilGMVF6OEnHMEXmCyyaldboV4LcCPWYnGXVeEQdhRZ9fypApdhG65v+D7GPhwWdjYt7HQUK7GiEfslNhRZtbcL8EG81rDH8TI+G7SyIqtAXqYp1uGRxvT6Iqu2N+OTvvyHG7DvcEv0DYT1gasiq9YJO/06urflZbpxNuAyvBr1z7EE77eBBoA/irn7o2trXqar+4Ej2Bn177Ecx04V1oBOYZVwgmEiL9N5TeATuDDqGY7PFdaATuP2aM7HMzXwTDweJ8ZxcEids4VT2RX6DV6K5lhepgsSrME50flUS41VwrUY9/8DN5vUNXu4P8Fd0XEAR1uS58XxIeGSr2yjFVn1MyajeWeCa6MxOTjlP3KioV+FfXmZFh3y9sRxUYLLonFkcGyrbM7LdH9eptcNianv5SUJFkTjtzkC4UZ8MGS+vmLzE/wZjXNPA3gI9w2Zr2tPjQgt7HwsnCNse5FV61tirozjDwm+isbNHYqf0dB/xD0dYHBTHA8nZlraclzckjgdxwkswtttpLxMzzPTcXYleBN/R8eTLfkf4gbcjV/bYI2avai/kWAKz0XHhrjy2eR3fNIRJC/TSzEWza1FVh2r29PT+CPqu7sW7CDvxPGk2K9r4HEzLe5y7MVZp0PKy3Q3ronmvUVW/UX4D9ayB4/iBaFJH8QDOvzt+0BL8LrwwoNNRVZN1PMjffEv4h/hl3I1Po0LeEW43MNAo8ILb6zhfqzIqmebcbO92m6N0OYBelc4pYNebStwRyP2W+HVVvYX7t9hLe8JO9wUV70Qt8VvmBzFDmwpsurEoIDZgLVsid8aYddLcQUuEO7WL0JrrIQH11tFVp0cVvBfVZDA+HDoxOQAAAAASUVORK5CYII=");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,57 +240,55 @@ html, body {
|
||||
line-height: 1.7em;
|
||||
top: 8px;
|
||||
right: 75px;
|
||||
background-color: #D1D1D1;
|
||||
color: #080C0F;
|
||||
background-color: #d1d1d1;
|
||||
color: #080c0f;
|
||||
padding: 0 7px;
|
||||
padding-top: 2px;
|
||||
border-radius: 4px;
|
||||
opacity: 0;
|
||||
transition: opacity .3s;
|
||||
transition: opacity 0.3s;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
small {
|
||||
opacity: .3;
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ### RESPONSIVE
|
||||
@media (max-width: 1364px) {
|
||||
#content>.inner>section.materials>header>h1 {
|
||||
#content > .inner > section.materials > header > h1 {
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
#content>.inner>section.materials>article>.details>h1 {
|
||||
#content > .inner > section.materials > article > .details > h1 {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
#content>.inner>section.materials>article>.details>blockquote {
|
||||
#content > .inner > section.materials > article > .details > blockquote {
|
||||
font-size: 17px;
|
||||
line-height: 24px;
|
||||
-webkit-line-clamp: 4;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 16px!important;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
#paginator>header>h1 {
|
||||
font-size: 30px!important;
|
||||
#paginator > header > h1 {
|
||||
font-size: 30px !important;
|
||||
}
|
||||
|
||||
#paginator>.paginator-wrapper>.paginator-box {
|
||||
#paginator > .paginator-wrapper > .paginator-box {
|
||||
transform: scale(1.5);
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#paginator>.paginator-wrapper>small:first-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#paginator>.paginator-wrapper>small:last-child {
|
||||
#paginator > .paginator-wrapper > small:first-child,
|
||||
#paginator > .paginator-wrapper > small:last-child {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,29 @@
|
||||
/*
|
||||
SOME DEFAULT CSS.
|
||||
*/
|
||||
html, body {
|
||||
// ### BASE STYLES
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
min-width: 100vw;
|
||||
|
||||
background-color: #4C5062;
|
||||
background-color: #4c5062;
|
||||
color: white;
|
||||
|
||||
|
||||
// assistant page background
|
||||
&.assist-page {
|
||||
background: rgb(24,123,123);
|
||||
background: -moz-radial-gradient(circle, rgba(24,123,123,0.4906337535014006) 0%, rgba(13,15,19,1) 64%);
|
||||
background: -webkit-radial-gradient(circle, rgba(24,123,123,0.4906337535014006) 0%, rgba(13,15,19,1) 64%);
|
||||
background: radial-gradient(circle, rgba(24,123,123,0.4906337535014006) 0%, rgba(13,15,19,1) 64%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#187b7b",endColorstr="#0d0f13",GradientType=1);
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
rgba(24, 123, 123, 0.49) 0%,
|
||||
rgba(13, 15, 19, 1) 64%
|
||||
);
|
||||
|
||||
&.assist-active {
|
||||
background: rgb(24,81,123);
|
||||
background: -moz-radial-gradient(circle, rgba(24,81,123,0.6418942577030813) 0%, rgba(13,15,19,1) 64%);
|
||||
background: -webkit-radial-gradient(circle, rgba(24,81,123,0.6418942577030813) 0%, rgba(13,15,19,1) 64%);
|
||||
background: radial-gradient(circle, rgba(24,81,123,0.6418942577030813) 0%, rgba(13,15,19,1) 64%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#18517b",endColorstr="#0d0f13",GradientType=1);
|
||||
background: radial-gradient(
|
||||
circle,
|
||||
rgba(24, 81, 123, 0.64) 0%,
|
||||
rgba(13, 15, 19, 1) 64%
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +43,8 @@ html, body {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
|
||||
a {
|
||||
color: #2A9CD0;
|
||||
color: #2a9cd0;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
|
||||
@@ -57,29 +54,32 @@ a {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
OVERRIDES.
|
||||
*/
|
||||
// ### LAYOUT OVERRIDES
|
||||
|
||||
#wrapper {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#header, main {
|
||||
#header,
|
||||
main {
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
select, input {
|
||||
color: #ccc!important;
|
||||
// ### FORM OVERRIDES
|
||||
|
||||
select,
|
||||
input {
|
||||
color: #ccc !important;
|
||||
}
|
||||
|
||||
.form {
|
||||
label {
|
||||
font-weight: bold!important;
|
||||
color: #8AC832!important;
|
||||
font-size: 15px!important;
|
||||
font-weight: bold !important;
|
||||
color: #8ac832 !important;
|
||||
font-size: 15px !important;
|
||||
border-bottom: 1px dotted gray;
|
||||
margin-bottom: 10px!important;
|
||||
margin-bottom: 10px !important;
|
||||
|
||||
& + div {
|
||||
line-height: 1.2em;
|
||||
@@ -87,6 +87,6 @@ select, input {
|
||||
}
|
||||
|
||||
.svelteui-Tab-label {
|
||||
font-size: 18px!important;
|
||||
font-size: 18px !important;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,27 @@
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { is_listening, isListening } from "@/stores"
|
||||
import { clearInterval, clearTimeout, setInterval, setTimeout } from 'worker-timers';
|
||||
|
||||
// setInterval(() => {
|
||||
// (async () => {
|
||||
// is_listening.set(await invoke("is_listening"));
|
||||
// })().catch(err => {
|
||||
// console.error(err);
|
||||
// });
|
||||
// }, 1000);
|
||||
// ### UTILITY FUNCTIONS
|
||||
|
||||
export function startListening() {
|
||||
(async () => {
|
||||
invoke('start_listening')
|
||||
.then((message) => {
|
||||
is_listening.set(true);
|
||||
})
|
||||
.catch((error) => {
|
||||
is_listening.set(false);
|
||||
console.error(error);
|
||||
// alert("Ошибка: " + error);
|
||||
})
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
export function capitalizeFirstLetter(str: string): string {
|
||||
if (!str) return ""
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
export function stopListening(callback: () => void) {
|
||||
(async () => {
|
||||
invoke('stop_listening')
|
||||
.then((message) => {
|
||||
is_listening.set(false);
|
||||
if(callback) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
})
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
export function showInExplorer(path: string): void {
|
||||
invoke("show_in_folder", { path })
|
||||
.catch(err => console.error("failed to open explorer:", err))
|
||||
}
|
||||
|
||||
export function capitalizeFirstLetter(string: string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
// ### LISTENER FUNCTIONS
|
||||
// removed since gui now doesn't handle listening
|
||||
|
||||
export function startListening(): void {
|
||||
// disabled in GUI - listening is handled by the tray app
|
||||
console.log("[gui] listening not available in settings app")
|
||||
}
|
||||
|
||||
export function showInExplorer(path: any) {
|
||||
(async () => {
|
||||
invoke('show_in_folder', {path: path})
|
||||
.then((message) => {})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
// alert("Ошибка: " + error);
|
||||
})
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
export function stopListening(callback?: () => void): void {
|
||||
// disabled in GUI - just call the callback if provided
|
||||
console.log("[gui] listening not available in settings app")
|
||||
if (callback) callback()
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
// Klondike project old CSS file
|
||||
import "./css/main.scss";
|
||||
// ### STYLES
|
||||
import "./css/main.scss"
|
||||
import "./css/styles.scss"
|
||||
|
||||
// App current CSS file
|
||||
import "./css/styles.scss";
|
||||
// ### APP
|
||||
import App from "./App.svelte"
|
||||
|
||||
// deploy app
|
||||
import App from "./App.svelte";
|
||||
const app = new App({
|
||||
target: document.getElementById("app")!,
|
||||
});
|
||||
target: document.getElementById("app")!
|
||||
})
|
||||
|
||||
export default app;
|
||||
export default app
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<!-- _layout.svelte -->
|
||||
<script>
|
||||
import { Container } from '@svelteuidev/core'
|
||||
import Header from '@/components/Header.svelte'
|
||||
<script lang="ts">
|
||||
import { Container } from "@svelteuidev/core"
|
||||
import Header from "@/components/Header.svelte"
|
||||
</script>
|
||||
|
||||
<Container fluid id="wrapper">
|
||||
|
||||
@@ -1,23 +1,39 @@
|
||||
<script lang="ts">
|
||||
import { Notification, Space } from "@svelteuidev/core"
|
||||
import { InfoCircled } from "radix-icons-svelte"
|
||||
|
||||
import HDivider from "@/components/elements/HDivider.svelte"
|
||||
import Footer from "@/components/Footer.svelte"
|
||||
import { appInfo } from "@/stores"
|
||||
|
||||
import { Notification, Space } from '@svelteuidev/core';
|
||||
import { InfoCircled } from 'radix-icons-svelte';
|
||||
|
||||
import { tg_official_link } from "@/stores";
|
||||
let tgLink = ""
|
||||
appInfo.subscribe(info => {
|
||||
tgLink = info.tgOfficialLink
|
||||
})
|
||||
</script>
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<Notification title='[404] Этот раздел еще находится в разработке!' icon={InfoCircled} color='blue' withCloseButton={false}>
|
||||
Тут будет список команд + полноценный редактор команд.<br>
|
||||
Следите за обновлениями в <a href="{tg_official_link}" target="_blank">нашем телеграм канале</a>!
|
||||
<Notification
|
||||
title="[404] Этот раздел еще находится в разработке!"
|
||||
icon={InfoCircled}
|
||||
color="blue"
|
||||
withCloseButton={false}
|
||||
>
|
||||
Тут будет список команд + полноценный редактор команд.<br />
|
||||
Следите за обновлениями в <a href={tgLink} target="_blank">нашем телеграм канале</a>!
|
||||
</Notification>
|
||||
|
||||
<div style="text-align: center;margin-top: 25px;">
|
||||
<img src="/media/images/tenor.gif" alt="bruh" width="320px">
|
||||
<div class="placeholder-image">
|
||||
<img src="/media/images/tenor.gif" alt="bruh" width="320px" />
|
||||
</div>
|
||||
|
||||
<HDivider />
|
||||
<Footer />
|
||||
|
||||
<style>
|
||||
.placeholder-image {
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,71 +1,46 @@
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte"
|
||||
import { Notification, Space } from "@svelteuidev/core"
|
||||
import { InfoCircled } from "radix-icons-svelte"
|
||||
|
||||
import SearchBar from "@/components/elements/SearchBar.svelte"
|
||||
import ArcReactor from "@/components/elements/ArcReactor.svelte"
|
||||
import HDivider from "@/components/elements/HDivider.svelte"
|
||||
import Stats from "@/components/elements/Stats.svelte"
|
||||
import Footer from "@/components/Footer.svelte"
|
||||
|
||||
import { Notification, Space } from '@svelteuidev/core'
|
||||
import { InfoCircled } from 'radix-icons-svelte'
|
||||
import { onMount, onDestroy } from 'svelte'
|
||||
import { isListening } from "@/stores"
|
||||
|
||||
onMount(async () => {
|
||||
document.body.classList.add('assist-page');
|
||||
});
|
||||
let listening = false
|
||||
isListening.subscribe(value => {
|
||||
listening = value
|
||||
})
|
||||
|
||||
onDestroy(async () => {
|
||||
document.body.classList.remove('assist-page');
|
||||
});
|
||||
onMount(() => {
|
||||
document.body.classList.add("assist-page")
|
||||
})
|
||||
|
||||
import { is_listening } from "@/stores"
|
||||
let is_listening__val: boolean;
|
||||
is_listening.subscribe(value => {
|
||||
is_listening__val = value;
|
||||
});
|
||||
onDestroy(() => {
|
||||
document.body.classList.remove("assist-page")
|
||||
})
|
||||
</script>
|
||||
|
||||
<HDivider />
|
||||
{#if !is_listening__val}
|
||||
<Notification title='Внимание!' icon={InfoCircled} color='cyan' withCloseButton={false}>
|
||||
В данный момент ассистент не прослушивает команды.<br />
|
||||
Пожалуйста, <a href="/settings">перейдите в настройки</a> и введите ключ Picovoice.
|
||||
</Notification>
|
||||
<!-- <SearchBar /> -->
|
||||
|
||||
{#if !listening}
|
||||
<Notification
|
||||
title="Внимание!"
|
||||
icon={InfoCircled}
|
||||
color="cyan"
|
||||
withCloseButton={false}
|
||||
>
|
||||
В данный момент ассистент не прослушивает команды.<br />
|
||||
Пожалуйста, <a href="/settings">перейдите в настройки</a> и введите ключ Picovoice.
|
||||
</Notification>
|
||||
{:else}
|
||||
<!-- <SearchBar /> -->
|
||||
<ArcReactor />
|
||||
<ArcReactor />
|
||||
{/if}
|
||||
<HDivider no_margin />
|
||||
|
||||
<HDivider noMargin />
|
||||
<Stats />
|
||||
<Footer />
|
||||
|
||||
|
||||
<!--
|
||||
<Title order={1}>This is h1 title</Title>
|
||||
<Title order={1} variant='gradient' gradient={{from: 'blue', to: 'red', deg: 45}}>This is h1 title with a twist</Title>
|
||||
|
||||
<Menu>
|
||||
<Button slot="control" variant="gradient" gradient={{ from: 'blue', to: 'teal', deg: 50 }} radius="md" size="md">Toggle Menu</Button>
|
||||
<Menu.Label>Application</Menu.Label>
|
||||
<Menu.Item icon={Gear}>Settings</Menu.Item>
|
||||
<Menu.Item icon={ChatBubble}>Messages</Menu.Item>
|
||||
<Menu.Item icon={Camera}>Gallery</Menu.Item>
|
||||
<Menu.Item icon={MagnifyingGlass}>
|
||||
<svelte:fragment slot='rightSection'>
|
||||
<Text size="xs" color="dimmed">⌘K</Text>
|
||||
</svelte:fragment>
|
||||
Search
|
||||
</Menu.Item>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Menu.Label>Danger zone</Menu.Label>
|
||||
<Menu.Item icon={Width}>Transfer my data</Menu.Item>
|
||||
<Menu.Item color="red" icon={Trash}>Delete my account</Menu.Item>
|
||||
</Menu>
|
||||
|
||||
<Checkbox bind:checked={checked} label="I agree to sell my privacy" />
|
||||
{checked}
|
||||
{#if checked}
|
||||
YEP!
|
||||
{/if} -->
|
||||
@@ -1,186 +1,278 @@
|
||||
<script lang="ts">
|
||||
// IMPORTS
|
||||
import { onMount } from "svelte"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { goto } from '@roxi/routify'
|
||||
import { onMount } from 'svelte'
|
||||
import { startListening, stopListening, showInExplorer } from "@/functions";
|
||||
// import { setTimeout } from 'worker-timers';
|
||||
import { goto } from "@roxi/routify"
|
||||
import { setTimeout } from "worker-timers"
|
||||
|
||||
import { feedback_link, log_file_path } from "@/stores";
|
||||
import { showInExplorer, stopListening, startListening } from "@/functions"
|
||||
import { appInfo, assistantVoice } from "@/stores"
|
||||
|
||||
// COMPONENTS & STUFF
|
||||
import HDivider from "@/components/elements/HDivider.svelte"
|
||||
import Footer from "@/components/Footer.svelte"
|
||||
|
||||
import { Notification, Button, Text, Tabs, Space, Alert, Input, InputWrapper, NativeSelect } from '@svelteuidev/core';
|
||||
import { Check, Mix, Cube, Code, Gear, QuestionMarkCircled, CrossCircled } from 'radix-icons-svelte';
|
||||
import {
|
||||
Notification,
|
||||
Button,
|
||||
Text,
|
||||
Tabs,
|
||||
Space,
|
||||
Alert,
|
||||
Input,
|
||||
InputWrapper,
|
||||
NativeSelect
|
||||
} from "@svelteuidev/core"
|
||||
|
||||
// VARIABLES
|
||||
import {
|
||||
Check,
|
||||
Mix,
|
||||
Cube,
|
||||
Code,
|
||||
Gear,
|
||||
QuestionMarkCircled,
|
||||
CrossCircled
|
||||
} from "radix-icons-svelte"
|
||||
|
||||
let available_microphones: { label: string; value: number }[] = [];
|
||||
let settings_saved = false;
|
||||
let save_button_disabled = false;
|
||||
|
||||
let assistant_voice_val = ""; // shared
|
||||
let selected_microphone = "";
|
||||
|
||||
let selected_wake_word_engine = "";
|
||||
let api_key__picovoice = "";
|
||||
let api_key__openai = "";
|
||||
|
||||
// SHARED VALUES
|
||||
import { assistant_voice } from "@/stores"
|
||||
assistant_voice.subscribe(value => {
|
||||
assistant_voice_val = value;
|
||||
});
|
||||
|
||||
// FUNCTIONS
|
||||
async function save_settings() {
|
||||
save_button_disabled = true; // disable save button for a while
|
||||
settings_saved = false; // hide alert
|
||||
|
||||
await invoke("db_write", {key: "assistant_voice", val: assistant_voice_val});
|
||||
await invoke("db_write", {key: "selected_microphone", val: selected_microphone});
|
||||
|
||||
await invoke("db_write", {key: "selected_wake_word_engine", val: selected_wake_word_engine});
|
||||
await invoke("db_write", {key: "api_key__picovoice", val: api_key__picovoice});
|
||||
await invoke("db_write", {key: "api_key__openai", val: api_key__openai});
|
||||
|
||||
// update shared
|
||||
assistant_voice.set(assistant_voice_val);
|
||||
|
||||
settings_saved = true; // show alert
|
||||
setTimeout(() => {
|
||||
settings_saved = false; // hide alert again after N seconds
|
||||
}, 5000);
|
||||
|
||||
setTimeout(() => {
|
||||
save_button_disabled = false; // enable save button again
|
||||
}, 1000);
|
||||
|
||||
// restart listening everytime new settings is saved
|
||||
stopListening(() => {
|
||||
startListening();
|
||||
});
|
||||
// ### STATE
|
||||
interface MicrophoneOption {
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
|
||||
// CODE
|
||||
let availableMicrophones: MicrophoneOption[] = []
|
||||
let settingsSaved = false
|
||||
let saveButtonDisabled = false
|
||||
|
||||
// form values
|
||||
let voiceVal = ""
|
||||
let selectedMicrophone = ""
|
||||
let selectedWakeWordEngine = ""
|
||||
let apiKeyPicovoice = ""
|
||||
let apiKeyOpenai = ""
|
||||
|
||||
// subscribe to stores
|
||||
assistantVoice.subscribe(value => {
|
||||
voiceVal = value
|
||||
})
|
||||
|
||||
let feedbackLink = ""
|
||||
let logFilePath = ""
|
||||
appInfo.subscribe(info => {
|
||||
feedbackLink = info.feedbackLink
|
||||
logFilePath = info.logFilePath
|
||||
})
|
||||
|
||||
// ### FUNCTIONS
|
||||
async function saveSettings() {
|
||||
saveButtonDisabled = true
|
||||
settingsSaved = false
|
||||
|
||||
try {
|
||||
await Promise.all([
|
||||
invoke("db_write", { key: "assistant_voice", val: voiceVal }),
|
||||
invoke("db_write", { key: "selected_microphone", val: selectedMicrophone }),
|
||||
invoke("db_write", { key: "selected_wake_word_engine", val: selectedWakeWordEngine }),
|
||||
invoke("db_write", { key: "api_key__picovoice", val: apiKeyPicovoice }),
|
||||
invoke("db_write", { key: "api_key__openai", val: apiKeyOpenai })
|
||||
])
|
||||
|
||||
// update shared store
|
||||
assistantVoice.set(voiceVal)
|
||||
settingsSaved = true
|
||||
|
||||
// hide alert after 5 seconds
|
||||
setTimeout(() => {
|
||||
settingsSaved = false
|
||||
}, 5000)
|
||||
|
||||
// restart listening with new settings
|
||||
stopListening(() => startListening())
|
||||
} catch (err) {
|
||||
console.error("failed to save settings:", err)
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
saveButtonDisabled = false
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// ### INIT
|
||||
onMount(async () => {
|
||||
// preload some vars
|
||||
let _available_microphones: Array<Number> = await invoke("pv_get_audio_devices");
|
||||
Object.entries(_available_microphones).forEach(entry => {
|
||||
const [k, v] = entry;
|
||||
try {
|
||||
// load microphones
|
||||
const mics = await invoke<string[]>("pv_get_audio_devices")
|
||||
availableMicrophones = mics.map((name, idx) => ({
|
||||
label: name,
|
||||
value: String(idx)
|
||||
}))
|
||||
|
||||
available_microphones.push({
|
||||
label: String(v),
|
||||
value: Number(k)
|
||||
});
|
||||
});
|
||||
|
||||
available_microphones = available_microphones; // update component options
|
||||
|
||||
// load values from db
|
||||
// assistant_voice.set(await invoke("db_read", {key: "assistant_voice"}));
|
||||
selected_microphone = await invoke("db_read", {key: "selected_microphone"});
|
||||
|
||||
selected_wake_word_engine = await invoke("db_read", {key: "selected_wake_word_engine"});
|
||||
api_key__picovoice = await invoke("db_read", {key: "api_key__picovoice"});
|
||||
api_key__openai = await invoke("db_read", {key: "api_key__openai"});
|
||||
});
|
||||
// load settings from db
|
||||
const [mic, wakeWord, pico, openai] = await Promise.all([
|
||||
invoke<string>("db_read", { key: "selected_microphone" }),
|
||||
invoke<string>("db_read", { key: "selected_wake_word_engine" }),
|
||||
invoke<string>("db_read", { key: "api_key__picovoice" }),
|
||||
invoke<string>("db_read", { key: "api_key__openai" })
|
||||
])
|
||||
|
||||
selectedMicrophone = mic
|
||||
selectedWakeWordEngine = wakeWord
|
||||
apiKeyPicovoice = pico
|
||||
apiKeyOpenai = openai
|
||||
} catch (err) {
|
||||
console.error("failed to load settings:", err)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<Notification title='БЕТА версия!' icon={QuestionMarkCircled} color='blue' withCloseButton={false}>
|
||||
<Notification
|
||||
title="БЕТА версия!"
|
||||
icon={QuestionMarkCircled}
|
||||
color="blue"
|
||||
withCloseButton={false}
|
||||
>
|
||||
Часть функций может работать некорректно.<br />
|
||||
Сообщайте обо всех найденных багах в <a href="{feedback_link}" target="_blank">наш телеграм бот</a>.
|
||||
Сообщайте обо всех найденных багах в <a href={feedbackLink} target="_blank">наш телеграм бот</a>.
|
||||
<Space h="sm" />
|
||||
<Button color="gray" radius="md" size="xs" uppercase on:click={() => {showInExplorer(log_file_path)}}>Открыть папку с логами</Button>
|
||||
<Button
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="xs"
|
||||
uppercase
|
||||
on:click={() => showInExplorer(logFilePath)}
|
||||
>
|
||||
Открыть папку с логами
|
||||
</Button>
|
||||
</Notification>
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
{#if settings_saved }
|
||||
<Notification title='Настройки сохранены!' icon={Check} color='teal' on:close="{() => {settings_saved = false}}"></Notification>
|
||||
<Space h="xl" />
|
||||
{#if settingsSaved}
|
||||
<Notification
|
||||
title="Настройки сохранены!"
|
||||
icon={Check}
|
||||
color="teal"
|
||||
on:close={() => { settingsSaved = false }}
|
||||
/>
|
||||
<Space h="xl" />
|
||||
{/if}
|
||||
|
||||
<Tabs class="form" color='#8AC832' position="left">
|
||||
<Tabs.Tab label='Общее' icon={Gear}>
|
||||
<Tabs class="form" color="#8AC832" position="left">
|
||||
<!-- general tab -->
|
||||
<Tabs.Tab label="Общее" icon={Gear}>
|
||||
<Space h="sm" />
|
||||
|
||||
<NativeSelect data={[
|
||||
{ label: 'Jarvis ремейк (от Хауди)', value: 'jarvis-remake' },
|
||||
{ label: 'Jarvis OG (из фильмов)', value: 'jarvis-og' }
|
||||
<NativeSelect
|
||||
data={[
|
||||
{ label: "Jarvis ремейк (от Хауди)", value: "jarvis-remake" },
|
||||
{ label: "Jarvis OG (из фильмов)", value: "jarvis-og" }
|
||||
]}
|
||||
label="Голос ассистента"
|
||||
description="Не все команды работают со всеми звуковыми пакетами."
|
||||
variant="filled"
|
||||
bind:value={assistant_voice_val}
|
||||
bind:value={voiceVal}
|
||||
/>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab label='Устройства' icon={Mix}>
|
||||
<Space h="sm" />
|
||||
|
||||
<NativeSelect data={available_microphones}
|
||||
<!-- devices tab -->
|
||||
<Tabs.Tab label="Устройства" icon={Mix}>
|
||||
<Space h="sm" />
|
||||
<NativeSelect
|
||||
data={availableMicrophones}
|
||||
label="Выберите микрофон"
|
||||
description="Его будет слушать ассистент."
|
||||
variant="filled"
|
||||
bind:value={selected_microphone}
|
||||
bind:value={selectedMicrophone}
|
||||
/>
|
||||
</Tabs.Tab>
|
||||
<Tabs.Tab label='Нейросети' icon={Cube}>
|
||||
<Space h="sm" />
|
||||
|
||||
<NativeSelect data={[
|
||||
{ label: 'Rustpotter', value: 'Rustpotter' },
|
||||
{ label: 'Vosk (медленный)', value: 'Vosk' },
|
||||
{ label: 'Picovoice Porcupine (требует API ключ)', value: 'Picovoice' }
|
||||
<!-- neural networks tab -->
|
||||
<Tabs.Tab label="Нейросети" icon={Cube}>
|
||||
<Space h="sm" />
|
||||
<NativeSelect
|
||||
data={[
|
||||
{ label: "Rustpotter", value: "Rustpotter" },
|
||||
{ label: "Vosk (медленный)", value: "Vosk" },
|
||||
{ label: "Picovoice Porcupine (требует API ключ)", value: "Picovoice" }
|
||||
]}
|
||||
label="Распознавание активационной фразы (Wake Word)"
|
||||
description="Выберите, какая нейросеть будет отвечать за распознавание активационной фразы."
|
||||
variant="filled"
|
||||
bind:value={selected_wake_word_engine}
|
||||
bind:value={selectedWakeWordEngine}
|
||||
/>
|
||||
|
||||
{#if selected_wake_word_engine == "picovoice"}
|
||||
{#if selectedWakeWordEngine === "picovoice"}
|
||||
<Space h="sm" />
|
||||
<Alert title="Внимание!" color="#868E96" variant="outline">
|
||||
|
||||
<Notification title='Эта нейросеть работает не у всех!' icon={CrossCircled} color='orange' withCloseButton={false}>
|
||||
<Notification
|
||||
title="Эта нейросеть работает не у всех!"
|
||||
icon={CrossCircled}
|
||||
color="orange"
|
||||
withCloseButton={false}
|
||||
>
|
||||
Мы ждем официального патча от разработчиков.
|
||||
</Notification>
|
||||
<Space h="sm" />
|
||||
|
||||
<Text size='sm' color="gray">
|
||||
<Text size="sm" color="gray">
|
||||
Введите сюда свой ключ Picovoice.<br />
|
||||
Он выдается бесплатно при регистрации в <a href='https://console.picovoice.ai/' target="_blank">Picovoice Console</a>.<br>
|
||||
Он выдается бесплатно при регистрации в
|
||||
<a href="https://console.picovoice.ai/" target="_blank">Picovoice Console</a>.
|
||||
</Text>
|
||||
<Space h="sm" />
|
||||
<Input icon={Code} placeholder='Ключ Picovoice' variant='filled' autocomplete="off" bind:value={api_key__picovoice}/>
|
||||
|
||||
<Input
|
||||
icon={Code}
|
||||
placeholder="Ключ Picovoice"
|
||||
variant="filled"
|
||||
autocomplete="off"
|
||||
bind:value={apiKeyPicovoice}
|
||||
/>
|
||||
</Alert>
|
||||
{/if}
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<InputWrapper label="Ключ OpenAI">
|
||||
<!-- <Text size='sm' color="gray">Введите сюда свой ключ OpenAI, он требуется для работы ChatGPT.<br />Получить его можно <a href="https://chat.openai.com/auth/login" target="_blank">на официальном сайте OpenAI</a>.</Text> -->
|
||||
<Text size='sm' color="gray">В данный момент ChatGPT <u>не поддерживается</u>. Он будет добавлен в ближайших обновлениях.</Text>
|
||||
<Text size="sm" color="gray">
|
||||
В данный момент ChatGPT <u>не поддерживается</u>.
|
||||
Он будет добавлен в ближайших обновлениях.
|
||||
</Text>
|
||||
<Space h="sm" />
|
||||
<Input icon={Code} placeholder='Ключ OpenAI' variant='filled' autocomplete="off" bind:value={api_key__openai} disabled/>
|
||||
<Input
|
||||
icon={Code}
|
||||
placeholder="Ключ OpenAI"
|
||||
variant="filled"
|
||||
autocomplete="off"
|
||||
bind:value={apiKeyOpenai}
|
||||
disabled
|
||||
/>
|
||||
</InputWrapper>
|
||||
</Tabs.Tab>
|
||||
</Tabs>
|
||||
|
||||
<Space h="xl" />
|
||||
|
||||
<Button color="lime" radius="md" size="sm" uppercase ripple fullSize on:click={save_settings} disabled={save_button_disabled}>
|
||||
<Button
|
||||
color="lime"
|
||||
radius="md"
|
||||
size="sm"
|
||||
uppercase
|
||||
ripple
|
||||
fullSize
|
||||
on:click={saveSettings}
|
||||
disabled={saveButtonDisabled}
|
||||
>
|
||||
Сохранить
|
||||
</Button>
|
||||
|
||||
<Space h="sm" />
|
||||
<Button color="gray" radius="md" size="sm" uppercase fullSize on:click={() => {$goto('/')}}>
|
||||
|
||||
<Button
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="sm"
|
||||
uppercase
|
||||
fullSize
|
||||
on:click={() => $goto("/")}
|
||||
>
|
||||
Назад
|
||||
</Button>
|
||||
|
||||
|
||||
@@ -1,34 +1,50 @@
|
||||
import { writable, get } from "svelte/store"
|
||||
import { invoke } from "@tauri-apps/api/core"
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
// listen state
|
||||
export const is_listening = writable(true);
|
||||
let is_listening__val: boolean;
|
||||
is_listening.subscribe(value => {
|
||||
is_listening__val = value;
|
||||
});
|
||||
export function isListening() {return is_listening__val}
|
||||
// ### LISTENING STATE
|
||||
// note: defaults to false since GUI doesn't have listening capability
|
||||
export const isListening = writable(false)
|
||||
|
||||
// assistant voice
|
||||
export const assistant_voice = writable("");
|
||||
// ### ASSISTANT VOICE
|
||||
export const assistantVoice = writable("")
|
||||
|
||||
(async () => {
|
||||
assistant_voice.set(await invoke("db_read", {key: "assistant_voice"}));
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
// load voice setting from db
|
||||
async function loadVoiceSetting() {
|
||||
try {
|
||||
const voice = await invoke<string>("db_read", { key: "assistant_voice" })
|
||||
assistantVoice.set(voice)
|
||||
} catch (err) {
|
||||
console.error("failed to load voice setting:", err)
|
||||
}
|
||||
}
|
||||
loadVoiceSetting()
|
||||
|
||||
// etc
|
||||
export let tg_official_link = "";
|
||||
export let feedback_link = "";
|
||||
export let github_repository_link = "";
|
||||
export let log_file_path = "";
|
||||
// ### APP INFO
|
||||
// these are loaded once on startup
|
||||
export const appInfo = writable({
|
||||
tgOfficialLink: "",
|
||||
feedbackLink: "",
|
||||
repositoryLink: "",
|
||||
logFilePath: ""
|
||||
})
|
||||
|
||||
(async () => {
|
||||
tg_official_link = await invoke("get_tg_official_link")
|
||||
feedback_link = await invoke("get_feedback_link")
|
||||
github_repository_link = await invoke("get_repository_link")
|
||||
log_file_path = await invoke("get_log_file_path")
|
||||
})().catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
async function loadAppInfo() {
|
||||
try {
|
||||
const [tg, feedback, repo, logPath] = await Promise.all([
|
||||
invoke<string>("get_tg_official_link"),
|
||||
invoke<string>("get_feedback_link"),
|
||||
invoke<string>("get_repository_link"),
|
||||
invoke<string>("get_log_file_path")
|
||||
])
|
||||
|
||||
appInfo.set({
|
||||
tgOfficialLink: tg,
|
||||
feedbackLink: feedback,
|
||||
repositoryLink: repo,
|
||||
logFilePath: logPath
|
||||
})
|
||||
} catch (err) {
|
||||
console.error("failed to load app info:", err)
|
||||
}
|
||||
}
|
||||
loadAppInfo()
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// vite.config.ts
|
||||
import { defineConfig } from "file:///D:/Rust/jarvis-app/frontend/node_modules/vite/dist/node/index.js";
|
||||
import { svelte } from "file:///D:/Rust/jarvis-app/frontend/node_modules/@sveltejs/vite-plugin-svelte/src/index.js";
|
||||
import sveltePreprocess from "file:///D:/Rust/jarvis-app/frontend/node_modules/svelte-preprocess/dist/index.js";
|
||||
import tsconfigPaths from "file:///D:/Rust/jarvis-app/frontend/node_modules/vite-tsconfig-paths/dist/index.mjs";
|
||||
import routify from "file:///D:/Rust/jarvis-app/frontend/node_modules/@roxi/routify/lib/extra/vite-plugin/vite-plugin.js";
|
||||
var vite_config_default = defineConfig({
|
||||
plugins: [
|
||||
svelte({
|
||||
preprocess: [
|
||||
sveltePreprocess({
|
||||
typescript: true
|
||||
})
|
||||
],
|
||||
onwarn: (warning, handler) => {
|
||||
const { code, frame } = warning;
|
||||
if (code === "css-unused-selector")
|
||||
return;
|
||||
handler(warning);
|
||||
}
|
||||
}),
|
||||
routify(),
|
||||
tsconfigPaths()
|
||||
],
|
||||
clearScreen: false,
|
||||
server: {
|
||||
port: 1420,
|
||||
strictPort: true
|
||||
},
|
||||
envPrefix: ["VITE_", "TAURI_"],
|
||||
build: {
|
||||
target: process.env.TAURI_PLATFORM == "windows" ? "chrome105" : "safari13",
|
||||
minify: !process.env.TAURI_DEBUG ? "esbuild" : false,
|
||||
sourcemap: !!process.env.TAURI_DEBUG
|
||||
}
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxSdXN0XFxcXGphcnZpcy1hcHBcXFxcZnJvbnRlbmRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkQ6XFxcXFJ1c3RcXFxcamFydmlzLWFwcFxcXFxmcm9udGVuZFxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vRDovUnVzdC9qYXJ2aXMtYXBwL2Zyb250ZW5kL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSBcInZpdGVcIjtcclxuaW1wb3J0IHsgc3ZlbHRlIH0gZnJvbSBcIkBzdmVsdGVqcy92aXRlLXBsdWdpbi1zdmVsdGVcIjtcclxuaW1wb3J0IHN2ZWx0ZVByZXByb2Nlc3MgZnJvbSBcInN2ZWx0ZS1wcmVwcm9jZXNzXCI7XHJcbmltcG9ydCB0c2NvbmZpZ1BhdGhzIGZyb20gJ3ZpdGUtdHNjb25maWctcGF0aHMnXHJcbmltcG9ydCByb3V0aWZ5IGZyb20gJ0Byb3hpL3JvdXRpZnkvdml0ZS1wbHVnaW4nXHJcblxyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xyXG4gIHBsdWdpbnM6IFtcclxuICAgIHN2ZWx0ZSh7XHJcbiAgICAgIHByZXByb2Nlc3M6IFtcclxuICAgICAgICBzdmVsdGVQcmVwcm9jZXNzKHtcclxuICAgICAgICAgIHR5cGVzY3JpcHQ6IHRydWUsXHJcbiAgICAgICAgfSksXHJcbiAgICAgIF0sXHJcbiAgICAgIG9ud2FybjogKHdhcm5pbmcsIGhhbmRsZXIpID0+IHtcclxuICAgICAgICBjb25zdCB7IGNvZGUsIGZyYW1lIH0gPSB3YXJuaW5nO1xyXG4gICAgICAgIGlmIChjb2RlID09PSBcImNzcy11bnVzZWQtc2VsZWN0b3JcIilcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBoYW5kbGVyKHdhcm5pbmcpO1xyXG4gICAgICB9LFxyXG4gICAgfSksXHJcbiAgICByb3V0aWZ5KCksXHJcbiAgICB0c2NvbmZpZ1BhdGhzKClcclxuICBdLFxyXG5cclxuICBjbGVhclNjcmVlbjogZmFsc2UsXHJcbiAgc2VydmVyOiB7XHJcbiAgICBwb3J0OiAxNDIwLFxyXG4gICAgc3RyaWN0UG9ydDogdHJ1ZSxcclxuICB9LFxyXG4gIGVudlByZWZpeDogW1wiVklURV9cIiwgXCJUQVVSSV9cIl0sXHJcbiAgYnVpbGQ6IHtcclxuICAgIHRhcmdldDogcHJvY2Vzcy5lbnYuVEFVUklfUExBVEZPUk0gPT0gXCJ3aW5kb3dzXCIgPyBcImNocm9tZTEwNVwiIDogXCJzYWZhcmkxM1wiLFxyXG4gICAgbWluaWZ5OiAhcHJvY2Vzcy5lbnYuVEFVUklfREVCVUcgPyBcImVzYnVpbGRcIiA6IGZhbHNlLFxyXG4gICAgc291cmNlbWFwOiAhIXByb2Nlc3MuZW52LlRBVVJJX0RFQlVHLFxyXG4gIH0sXHJcbn0pOyJdLAogICJtYXBwaW5ncyI6ICI7QUFBMlEsU0FBUyxvQkFBb0I7QUFDeFMsU0FBUyxjQUFjO0FBQ3ZCLE9BQU8sc0JBQXNCO0FBQzdCLE9BQU8sbUJBQW1CO0FBQzFCLE9BQU8sYUFBYTtBQUVwQixJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixTQUFTO0FBQUEsSUFDUCxPQUFPO0FBQUEsTUFDTCxZQUFZO0FBQUEsUUFDVixpQkFBaUI7QUFBQSxVQUNmLFlBQVk7QUFBQSxRQUNkLENBQUM7QUFBQSxNQUNIO0FBQUEsTUFDQSxRQUFRLENBQUMsU0FBUyxZQUFZO0FBQzVCLGNBQU0sRUFBRSxNQUFNLE1BQU0sSUFBSTtBQUN4QixZQUFJLFNBQVM7QUFDVDtBQUVKLGdCQUFRLE9BQU87QUFBQSxNQUNqQjtBQUFBLElBQ0YsQ0FBQztBQUFBLElBQ0QsUUFBUTtBQUFBLElBQ1IsY0FBYztBQUFBLEVBQ2hCO0FBQUEsRUFFQSxhQUFhO0FBQUEsRUFDYixRQUFRO0FBQUEsSUFDTixNQUFNO0FBQUEsSUFDTixZQUFZO0FBQUEsRUFDZDtBQUFBLEVBQ0EsV0FBVyxDQUFDLFNBQVMsUUFBUTtBQUFBLEVBQzdCLE9BQU87QUFBQSxJQUNMLFFBQVEsUUFBUSxJQUFJLGtCQUFrQixZQUFZLGNBQWM7QUFBQSxJQUNoRSxRQUFRLENBQUMsUUFBUSxJQUFJLGNBQWMsWUFBWTtBQUFBLElBQy9DLFdBQVcsQ0FBQyxDQUFDLFFBQVEsSUFBSTtBQUFBLEVBQzNCO0FBQ0YsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||
Reference in New Issue
Block a user