Repository: zircleUI/smarthome-tutorial
Branch: master
Commit: 65ef72c79c29
Files: 24
Total size: 27.3 KB
Directory structure:
gitextract_xtipvzq_/
├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── CHANGELOG.md
├── LICENSE
├── README.md
├── babel.config.js
├── package.json
├── public/
│ └── index.html
└── src/
├── App.vue
├── main.js
└── views/
├── device.vue
├── devices.vue
├── family.vue
├── home.vue
├── living.vue
├── logs.vue
├── rooms.vue
├── scenes.vue
├── search.vue
├── settings.vue
├── status.vue
└── tv.vue
================================================
FILE CONTENTS
================================================
================================================
FILE: .browserslistrc
================================================
> 1%
last 2 versions
not ie <= 8
================================================
FILE: .eslintrc.js
================================================
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'@vue/standard'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
}
================================================
FILE: .gitignore
================================================
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
================================================
FILE: .postcssrc.js
================================================
module.exports = {
plugins: {
autoprefixer: {}
}
}
================================================
FILE: CHANGELOG.md
================================================
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [0.1.6](https://github.com/zircleui/tutorial/compare/v0.1.5...v0.1.6) (2019-05-02)
<a name="0.1.5"></a>
## [0.1.5](https://github.com/zircleui/tutorial/compare/v0.1.4...v0.1.5) (2019-04-22)
<a name="0.1.4"></a>
## [0.1.4](https://github.com/zircleui/tutorial/compare/v0.1.3...v0.1.4) (2019-01-06)
<a name="0.1.3"></a>
## [0.1.3](https://github.com/zircleui/tutorial/compare/v0.1.2...v0.1.3) (2018-11-25)
### Bug Fixes
* 🐛 home name ([071b762](https://github.com/zircleui/tutorial/commit/071b762)), closes [#1](https://github.com/zircleui/tutorial/issues/1)
<a name="0.1.2"></a>
## [0.1.2](https://github.com/zircleui/tutorial/compare/v0.1.1...v0.1.2) (2018-11-19)
<a name="0.1.1"></a>
## 0.1.1 (2018-08-17)
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2018-present, Juan Martín Muda
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: README.md
================================================
# Zircle-ui: smart-home tutorial
> :wave: This app is powered by [**zircle-ui**](https://github.com/zircleUI/zircleUI) :rocket: and is part of [its official tutorial](https://zircleui.github.io/docs/tutorial/). You can play with a working demo on [**CodeSandbox**](https://codesandbox.io/s/23wlzq4l1r?view=preview)
<img src="https://raw.githubusercontent.com/zircleUI/docs/master/docs/.vuepress/public/smart-home.jpg" style="margin-top: 20px; display: block; margin-left: auto; margin-right: auto; width: 100%;" />
## Project setup
```
git clone https://github.com/zircleUI/tutorial.git
```
After cloning the repository, execute:
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
================================================
FILE: babel.config.js
================================================
module.exports = {
presets: [
'@vue/app'
]
}
================================================
FILE: package.json
================================================
{
"name": "smart-home",
"version": "0.1.6",
"description": "Demo app for zircle-ui tutorial",
"author": "Juan Martín Muda <juan.martin.muda@gmail.com>",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"keywords": [
"zircle",
"smart-home",
"tutorial",
"vue",
"javascript"
],
"dependencies": {
"leaflet": "^1.4.0",
"smoothie": "^1.35.0",
"vue": "^2.6.10",
"vue-router": "^3.0.6",
"zircle": "^1.2.5"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.6.0",
"@vue/cli-plugin-eslint": "^3.6.0",
"@vue/cli-service": "^3.6.0",
"@vue/eslint-config-standard": "^3.0.5",
"node-sass": "^4.12.0",
"sass-loader": "^7.0.1",
"vue-template-compiler": "^2.6.10"
},
"repository": {
"type": "git",
"url": "git+https://github.com/zircleui/tutorial.git"
},
"bugs": {
"url": "https://github.com/zircleui/tutorial/issues"
},
"homepage": "https://github.com/zircleui/tutorial#readme",
"license": "MIT"
}
================================================
FILE: public/index.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>smart-home</title>
</head>
<body>
<noscript>
<strong>We're sorry but smart-home doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
================================================
FILE: src/App.vue
================================================
<template>
<z-canvas :views='$options.components'></z-canvas>
</template>
<script>
// TO SET UP VUE-ROUTER UNCOMMENT THE FOLLOWING LINES
// import Vue from 'vue'
// import Router from 'vue-router'
// Vue.use(Router)
// const router = new Router()
export default {
components: {
tv: () => import('./views/tv'),
living: () => import('./views/living'),
search: () => import('./views/search'),
device: () => import('./views/device'),
home: () => import('./views/home'),
settings: () => import('./views/settings'),
rooms: () => import('./views/rooms'),
devices: () => import('./views/devices'),
status: () => import('./views/status'),
scenes: () => import('./views/scenes'),
family: () => import('./views/family'),
logs: () => import('./views/logs')
},
mounted () {
this.$zircle.config({
mode: 'full',
style: {
theme: 'black',
mode: 'dark'
},
debug: true
})
this.$zircle.setView('home')
}
}
</script>
<style>
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700');
@import url('https://use.fontawesome.com/releases/v5.1.0/css/all.css');
</style>
================================================
FILE: src/main.js
================================================
import Vue from 'vue'
import App from './App.vue'
import zircle from 'zircle'
import 'zircle/dist/zircle.css'
Vue.use(zircle)
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
================================================
FILE: src/views/device.vue
================================================
<template>
<z-view>
{{category}}
<z-spot slot="extension"
to-view='home'
:distance='130'
:angle='30'
size='small' >
{{qty}}
</z-spot>
</z-view>
</template>
<script>
/*eslint-disable*/
// just $route.params.category and $route.params.qty
export default {
computed: {
category () {
if (this.$zircle.getParams() !== undefined) {
return this.$zircle.getParams().category
}
},
qty () {
if (this.$zircle.getParams() !== undefined) {
return this.$zircle.getParams().qty
}
}
}
}
</script>
================================================
FILE: src/views/devices.vue
================================================
<template>
<z-view>
<section slot="extension">
<z-list
:items="devices"
:per-page="5">
<z-spot
slot-scope="props"
:index="props.index"
:distance="60"
:to-view="{ name: 'device', params: {category: props.category, qty: props.qty}}"
:label="props.category">
<span style="color: white;">{{props.qty}}</span>
<z-spot slot="extension"
:style="props.category === 'care' ? 'background-color: red; border: none;': 'background-color: green; border: none;'"
:angle='-45'
size='xxs'>
</z-spot>
</z-spot>
</z-list>
</section>
</z-view>
</template>
<script>
export default {
data () {
return {
devices: [
{ category: 'cameras & sensors', qty: 4 },
{ category: 'care', qty: 1 },
{ category: 'climate', qty: 2 },
{ category: 'doors & locks', qty: 2 },
{ category: 'energy', qty: 1 },
{ category: 'garage doors', qty: 1 },
{ category: 'home & family', qty: 6 },
{ category: 'lawn & garden', qty: 0 },
{ category: 'lights & switches', qty: 13 },
{ category: 'smoke & co', qty: 3 },
{ category: 'voice assistant', qty: 1 },
{ category: 'water', qty: 1 },
{ category: 'windows & blinds', qty: 3 },
{ category: 'entertainment', qty: 3 }
]
}
}
}
</script>
================================================
FILE: src/views/family.vue
================================================
<template>
<z-view label="Leaflet | OpenStreetMap | CartoDB" ref="map">
<div slot="media" :id="$zircle.getCurrentViewName()" style="height:100%; width: 100%;">
</div>
<section slot="extension">
<z-spot button
:angle="-90"
size="s"
:style="active === 0 ? 'border-color: purple; color: purple;' : ''"
label="Mary"
label-pos="top"
@click.native="showMe(0, 'purple')">
<i class="fas fa-female"></i>
</z-spot>
<z-spot button
:angle="30"
size="s"
label="John"
:style="active === 1 ? 'border-color: green; color: green;' : ''"
@click.native="showMe(1, 'green')">
<i class="fas fa-male"></i>
</z-spot>
<z-spot button
:angle="150"
size="s"
label="Peter"
:style="active === 2 ? 'border-color: orange; color: orange;' : ''"
@click.native="showMe(2, 'orange')">
<i class="fas fa-child"></i>
</z-spot>
</section>
</z-view>
</template>
<script>
/*eslint-disable*/
import L from 'leaflet'
export default {
data () {
return {
map: null,
markers: [],
active: ''
}
},
methods: {
initMap () {
this.map = L.map(this.$zircle.getCurrentViewName(), {attributionControl: false, zoomControl: false}).setView([38.63, -90.23], 14)
L.tileLayer(
'https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager/{z}/{x}/{y}.png',
{
zoom: 18
}).addTo(this.map)
this.markers.push(
L.marker([38.60, -90.20]).bindPopup("Mary at work").addTo(this.map),
L.marker([38.63, -90.23]).bindPopup("John at home.").addTo(this.map).openPopup(),
L.marker([38.66, -90.26]).bindPopup("Peter at school").addTo(this.map)
)
this.active = 1
this.showMe(1, 'green')
},
showMe (index, color) {
this.map.panTo(this.markers[index].getLatLng())
this.markers[index].openPopup()
this.active = index
this.$refs.map.$el.style.borderColor = color
}
},
mounted () {
this.initMap()
}
}
</script>
<style>
@import url('https://unpkg.com/leaflet@1.3.1/dist/leaflet.css');
</style>
================================================
FILE: src/views/home.vue
================================================
<template>
<z-view>
11:53 PM
<br>
Monday, Oct.
<br>
<br>
<h1>Night mode</h1>
<br>
Outside 29˚C, sunny
<br>
Inside 25˚C
<div slot="extension">
<!-- status monitor -->
<z-spot
style="background-color: orange; border-width: 4px; border-color: var(--background-color);"
:angle="-145"
size="m"
:distance="120"
to-view="status">
<i style="color: var( --accent-text-color)" class="fas fa-bell"></i><br>
<span style="color: var( --accent-text-color)">15</span>
</z-spot>
<!-- family-->
<z-spot
:angle="-30"
size="s"
:distance="120"
label="family"
label-pos="right"
to-view="family">
<i class="fas fa-map-marker-alt"></i>
</z-spot>
<!-- scenes-->
<z-spot
:angle="0"
size="s"
:distance="120"
label="scenes"
label-pos="right"
to-view="scenes">
4
</z-spot>
<!-- rooms-->
<z-spot
:angle="30"
size="s"
:distance="120"
label="Rooms"
label-pos="right"
to-view="rooms">
5
</z-spot>
<!-- devices-->
<z-spot
:angle="60"
:distance="120"
size="s"
label="Devices"
label-pos="right"
to-view="devices">
45
</z-spot>
<!-- settings-->
<z-spot
:angle="150"
:distance="120"
size="s"
label="Settings"
to-view="settings">
<i class="fas fa-sliders-h"></i>
</z-spot>
</div>
</z-view>
</template>
================================================
FILE: src/views/living.vue
================================================
<template>
<z-view
style="border-width: 8px"
slider
:progress="progress">
<span style="color: var(--accent-text-color)">Living room
<h1>{{activeScene}}</h1>
{{msg}}
</span>
<img slot="image" src="living.jpg" width="100%" height="100%" style="opacity: 0.3">
<div slot="extension">
<z-spot
v-for="(device, index) in devices"
:button="device.name !== 'AC'"
:knob="device.name === 'AC'"
v-bind.sync="device.temp"
:angle="1 + (180 / (devices.length - 1) * index)"
:distance="100"
size="m"
:to-view="device.view"
:label="device.name"
:key="'dev_' + index">
<i :class="device.icon"></i>
<z-spot slot="extension"
button
:angle="-45"
size="xxs"
:style="device.state === 'on' ? 'border-color: green; background-color: green;' : 'border-color: red; background-color: red;'">
</z-spot>
</z-spot>
<z-spot
v-for="(scene, index) in scenes"
button
size="s"
:angle="225 + (90 / (scenes.length - 1) * index)"
:distance="125"
:label="scene.name"
label-pos="top"
:key="'scn_' + index"
@click.native="showMe(scene.name)">
<i :class="scene.icon"></i>
</z-spot>
</div>
</z-view>
</template>
<script>
/*eslint-disable*/
export default {
data () {
return {
progress: 0,
msg: '',
activeScene: '',
devices: [],
scenes: [
{name: 'Relax', state: 'active', icon: 'fas fa-book'},
{name: 'Theatre', state: 'deactive', icon: 'fas fa-film'},
{name: 'Party', state: 'deactive', icon: 'fas fa-birthday-cake'}
]
}
},
computed: {
retrieveParams () {
if (this.$zircle.getParams() !== undefined) {
return this.$zircle.getParams().room
}
}
},
methods: {
log (data) {
console.log(data)
},
showMe (scene) {
if (this.activeScene !== scene) {
this.progress = 5
this.activeScene = scene
this.msg = 'Activating devices...'
var vm = this
var id = setInterval(function () {
if (vm.progress >= 100) {
clearInterval(id)
vm.progress = 0
vm.msg = scene.msg
} else if (vm.progress === 40) {
vm.msg = 'Applying rules...'
if (scene === 'Relax') {
vm.devices = [
{name: 'AC', state: 'on', temp: {qty: 24, unit: '˚C', min: 18, max: 32}},
{name: 'TV', state: 'off', vol: 14, bright: 30, source: 'youtube', icon: 'fas fa-tv', view: 'tv'},
{name: 'Hifi', state: 'on', vol: 14, icon: 'fas fa-music'},
{name: 'Ambient light', state: 'off', icon: 'far fa-lightbulb'}
]
} else if (scene === 'Theatre') {
vm.devices = [
{name: 'AC', state: 'on', temp: {qty: 18, unit: '˚C', min: 18, max: 32}},
{name: 'TV', state: 'on', vol: 14, bright: 30, source: 'youtube', icon: 'fas fa-tv', view: 'tv'},
{name: 'Hifi', state: 'off', vol: 14, icon: 'fas fa-music'},
{name: 'Ambient light', state: 'off', icon: 'far fa-lightbulb'}
]
} else if (scene === 'Party') {
vm.devices = [
{name: 'AC', state: 'on', temp: {qty: 20, unit: '˚C', min: 18, max: 32}},
{name: 'TV', state: 'off', vol: 14, bright: 30, source: 'youtube', icon: 'fas fa-tv', view: 'tv'},
{name: 'Hifi', state: 'on', vol: 14, icon: 'fas fa-music'},
{name: 'Ambient light', state: 'on', icon: 'far fa-lightbulb'}
]
}
vm.progress ++
} else {
vm.progress ++
}
}, 20)
} else {
this.msg = 'This scene is already activated'
}
}
},
created () {
this.showMe('Relax')
}
}
</script>
================================================
FILE: src/views/logs.vue
================================================
<template>
<z-view style="border-width: 6px" label="Console">
<ul>
<li v-for="(log, index) in console" :key="index">
{{log}}
</li>
</ul>
<div slot="extension">
<z-spot
v-show="console.length > 1"
button
:angle="45"
size="s"
:distance="120"
label="Reset"
@click.native="openDialog = true">
<i class="fas fa-trash"></i>
</z-spot>
<z-dialog v-if="openDialog" self-close v-on:done="openDialog = false">
Are your sure?
<div slot=extension>
<z-spot
class="success"
button
:angle="45"
size="s"
:distance="120"
@click.native="reset">
<i class="fas fa-check"></i>
</z-spot>
<z-spot
class="danger"
button
:angle="135"
size="s"
:distance="120"
@click.native="openDialog = false">
<i class="fas fa-times"></i>
</z-spot>
</div>
</z-dialog>
</div>
</z-view>
</template>
<script>
export default {
data () {
return {
openDialog: false,
console: [
'12:30pm - Mary arrived home',
'12:34pm - Peter arrived home',
'1:30pm - Relax scene activated',
'1:50pm - Peter arrived home',
'4:00pm - Away scene activated',
'5:10pm - Movement detected',
'5:10pm - Video alert sent to Peter',
'6:00pm - At Home scene activated',
'6:01pm - Ambient lights turned on',
'6:01pm - Playing Mary music list',
'6:15pm - Problem with camera device',
'6:16pm - Camera is working after reset',
'6:45pm - Ambient lights turned off',
'7:01pm - Theatre turned on',
'8:00pm - Night scene activaded'
]
}
},
methods: {
reset () {
this.console = ['No events available']
this.openDialog = false
}
}
}
</script>
<style>
li {
line-height: 40px;
border-bottom: 1px solid white
}
</style>
================================================
FILE: src/views/rooms.vue
================================================
<template>
<z-view>
Rooms
<section slot="extension">
<z-list
:items="rooms"
:per-page="3">
<z-spot
:distance="60"
slot-scope="props"
:index="props.index"
:to-view="props.name"
:label="props.name"
:image-path="props.image"
label-pos="bottom">
<z-spot slot="extension"
v-if="props.status"
style="background-color: red; border: none;"
:angle='-45'
size='xxs'>
</z-spot>
</z-spot>
</z-list>
<z-spot
button
:angle="45"
size="s"
:distance="120"
label="Add"
@click.native="openDialog = true">
<i class="fas fa-plus"></i>
</z-spot>
<z-dialog v-if="openDialog" self-close v-on:done="openDialog = false">
Add a new room?
<div slot=extension>
<z-spot
class="success"
button
:angle="45"
size="s"
:distance="120"
@click.native="openDialog = false">
<i class="fas fa-check"></i>
</z-spot>
<z-spot
class="danger"
button
:angle="135"
size="s"
:distance="120"
@click.native="openDialog = false">
<i class="fas fa-times"></i>
</z-spot>
</div>
</z-dialog>
</section>
</z-view>
</template>
<script>
export default {
data () {
return {
rooms: [
{ name: 'Living', devices: 6, image: './living.jpg' },
{ name: 'Bedroom', devices: 2, status: 'alert' },
{ name: 'Kitchen', devices: 5 },
{ name: 'Studio', devices: 1 },
{ name: 'Bath', devices: 1 }
],
openDialog: false
}
}
}
</script>
================================================
FILE: src/views/scenes.vue
================================================
<template>
<z-view
label="Scenes"
slider
:progress="progress"
:style="styleActive">
<h1>{{activeScene}}</h1>
<div style="height: 60px;">
{{msg}}
</div>
<div slot="extension">
<z-spot
v-for="(el, index) in elements"
button
size="s"
:distance="120"
:angle="325 + (90 / elements.length * index)"
:style="activeScene === el.scene ? styleActive : ''"
:key="index"
@click.native="showMe(el)">
<i class="fas" :class="el.icon"></i>
</z-spot>
</div>
</z-view>
</template>
<script>
export default {
data () {
return {
activeScene: 'Night',
color: 'blue',
msg: '',
progress: 0,
elements: [
{ scene: 'Day', color: 'orange', icon: 'fa-sun', msg: 'Cooling rooms, blinds opened, playing ambient music' },
{ scene: 'Night', color: 'blue', icon: 'fa-moon', msg: 'Blinds closed, AC in silence mode, motion sensors active' },
{ scene: 'Away', color: 'red', icon: 'fa-shield-alt', msg: 'Alarm armed, cameras activated, blinds closed' },
{ scene: 'At home', color: 'green', icon: 'fa-home', msg: 'Lights in ambient mode, playing relax music, coffee is being prepared' }
]
}
},
computed: {
styleActive () {
return {
borderWidth: '8px',
borderColor: this.color,
color: this.color
}
}
},
methods: {
showMe (el) {
if (this.activeScene !== el.scene) {
this.progress = 5
this.activeScene = el.scene
this.color = el.color
this.msg = 'Activating devices...'
var vm = this
var id = setInterval(function () {
if (vm.progress >= 100) {
clearInterval(id)
vm.progress = 0
vm.msg = el.msg
} else if (vm.progress === 40) {
vm.msg = 'Applying rules...'
vm.progress++
} else {
vm.progress++
}
}, 20)
} else {
this.msg = 'This scene is already activated'
}
}
}
}
</script>
================================================
FILE: src/views/search.vue
================================================
<template>
<z-view>
<form action="search_submit" method="get" accept-charset="utf-8">
<input type="text" name="devices">
</form>
<div slot="extension">
<z-spot
:angle="45"
size="m"
:distance="120"
label="Search"
to-view="devices">
<i class="fa fas-search"></i>
</z-spot>
</div>
</z-view>
</template>
<script>
export default {
data () {
return {
scene: 'Night scene'
}
},
mounted () {
}
}
</script>
================================================
FILE: src/views/settings.vue
================================================
<template>
<z-view label="Settings">
{{ theme }}
<div slot="extension">
<z-spot
v-for="(el, index) in elements"
button
size="xs"
:distance="120"
:angle="el.angle"
:label="el.label"
:label-pos="el.labelPos"
:class="$zircle.getTheme() === 'theme-' + el.label ||
$zircle.getThemeMode() === 'mode-' + el.label ? 'accent' : ''"
:key="index"
@click.native="changeStyle(el)"
/>
</div>
</z-view>
</template>
<script>
export default {
data () {
return {
theme: 'Select your theme',
elements: [
{ type: 'theme', angle: -50, label: 'blue', labelPos: 'right' },
{ type: 'theme', angle: -30, label: 'black', labelPos: 'right' },
{ type: 'theme', angle: -10, label: 'green', labelPos: 'right' },
{ type: 'theme', angle: 10, label: 'red', labelPos: 'right' },
{ type: 'theme', angle: 30, label: 'light-blue', labelPos: 'right' },
{ type: 'theme', angle: 50, label: 'gray', labelPos: 'right' },
{ type: 'mode', angle: 210, label: 'dark', labelPos: 'left' },
{ type: 'mode', angle: 190, label: 'dark-filled', labelPos: 'left' },
{ type: 'mode', angle: 170, label: 'light', labelPos: 'left' },
{ type: 'mode', angle: 150, label: 'light-filled', labelPos: 'left' }
]
}
},
methods: {
changeStyle (el) {
el.type === 'theme'
? this.$zircle.config({ style: { theme: el.label } })
: this.$zircle.config({ style: { mode: el.label } })
var theme = this.$zircle.getTheme().split('theme-')[1]
var mode = this.$zircle.getThemeMode().split('mode-')[1]
this.theme = `The theme is ${theme} ${mode}`
}
}
}
</script>
================================================
FILE: src/views/status.vue
================================================
<template>
<z-view label="Home status" style="background-color: black">
<canvas slot="media" id="smoothie-chart" style="height:50%; width: inherit;"></canvas>
<div slot="extension">
<z-spot
:angle="-45"
size="m"
:distance="120"
label="Events"
to-view="logs">
15
</z-spot>
</div>
</z-view>
</template>
<script>
import { TimeSeries, SmoothieChart } from 'smoothie'
export default {
data () {
return {
scene: 'Night scene'
}
},
mounted () {
// Random data
var line1 = new TimeSeries()
// Add random data points at irregular intervals
var maxYValue = 10000
var addValueLoop = function () {
setTimeout(function () {
// Generate a random value, centered around zero, raised to the power of 5
// so that larger values occur less frequently
var value = Math.pow(Math.random() * 2 - 1, 5) * maxYValue
line1.append(new Date().getTime(), value)
addValueLoop()
}, Math.random() * 500)
}
addValueLoop()
var smoothie = new SmoothieChart({
grid: {
strokeStyle: 'transparent',
borderVisible: false
},
tooltip: true,
labels: { disabled: true }
})
smoothie.addTimeSeries(line1, {
strokeStyle: 'rgb(0, 255, 0)',
fillStyle: 'rgba(0, 255, 0, 0.4)',
lineWidth: 2
})
smoothie.streamTo(document.getElementById('smoothie-chart'), 100)
}
}
</script>
================================================
FILE: src/views/tv.vue
================================================
<template>
<z-view>
<iframe slot="media" width="100%" height="100%" src="https://www.youtube.com/embed/aJOTlE1K90k" frameborder="0" allowfullscreen></iframe>
Channel 9
<div slot="extension">
<z-spot button
:distance='130'
:angle='-15'
size='s'>
+
</z-spot>
<z-spot button
:distance='130'
:angle='15'
size='s'>
-
</z-spot>
<z-spot button
class="success"
:distance='110'
:angle='-45'
size='s'>
<i class="fa fa-power-off"></i>
</z-spot>
<z-spot button
:distance='100'
:angle='135'
:progress="14"
size='s'
label="vol">
</z-spot>
<z-spot button
class="accent"
:distance='100'
:angle='45'
size='s'
label="ch.">
</z-spot>
</div>
</z-view>
</template>
<script>
/*eslint-disable*/
export default {
data () {
return {
items: [
{name: 'tv', state: 'on', vol: 14, bright: 30, channel: '3'},
{name: 'lights', state: 'on', color: 'red'},
{name: 'lights', state: 'on', color: 'green'},
{name: 'lights', state: 'off', color: 'white'},
{name: 'Air', state: 'on', temp: 29},
{name: 'Camera', state: 'off'}
]
}
},
computed: {
retrieveParams () {
if (this.$zircle.getParams() !== undefined) {
return this.$zircle.getParams().room
}
}
}
}
</script>
gitextract_xtipvzq_/
├── .browserslistrc
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── CHANGELOG.md
├── LICENSE
├── README.md
├── babel.config.js
├── package.json
├── public/
│ └── index.html
└── src/
├── App.vue
├── main.js
└── views/
├── device.vue
├── devices.vue
├── family.vue
├── home.vue
├── living.vue
├── logs.vue
├── rooms.vue
├── scenes.vue
├── search.vue
├── settings.vue
├── status.vue
└── tv.vue
Condensed preview — 24 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (31K chars).
[
{
"path": ".browserslistrc",
"chars": 33,
"preview": "> 1%\nlast 2 versions\nnot ie <= 8\n"
},
{
"path": ".eslintrc.js",
"chars": 348,
"preview": "module.exports = {\n root: true,\n env: {\n node: true\n },\n 'extends': [\n 'plugin:vue/essential',\n '@vue/stand"
},
{
"path": ".gitignore",
"chars": 214,
"preview": ".DS_Store\nnode_modules\n/dist\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn"
},
{
"path": ".postcssrc.js",
"chars": 59,
"preview": "module.exports = {\n plugins: {\n autoprefixer: {}\n }\n}\n"
},
{
"path": "CHANGELOG.md",
"chars": 918,
"preview": "# Change Log\n\nAll notable changes to this project will be documented in this file. See [standard-version](https://github"
},
{
"path": "LICENSE",
"chars": 1092,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2018-present, Juan Martín Muda\n\nPermission is hereby granted, free of charge, to an"
},
{
"path": "README.md",
"chars": 838,
"preview": "# Zircle-ui: smart-home tutorial\n\n> :wave: This app is powered by [**zircle-ui**](https://github.com/zircleUI/zircleUI) "
},
{
"path": "babel.config.js",
"chars": 53,
"preview": "module.exports = {\n presets: [\n '@vue/app'\n ]\n}\n"
},
{
"path": "package.json",
"chars": 1077,
"preview": "{\n \"name\": \"smart-home\",\n \"version\": \"0.1.6\",\n \"description\": \"Demo app for zircle-ui tutorial\",\n \"author\": \"Juan Ma"
},
{
"path": "public/index.html",
"chars": 557,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE="
},
{
"path": "src/App.vue",
"chars": 1175,
"preview": "<template>\n <z-canvas :views='$options.components'></z-canvas>\n</template>\n<script>\n// TO SET UP VUE-ROUTER UNCOMMENT T"
},
{
"path": "src/main.js",
"chars": 210,
"preview": "import Vue from 'vue'\nimport App from './App.vue'\nimport zircle from 'zircle'\nimport 'zircle/dist/zircle.css'\nVue.use(zi"
},
{
"path": "src/views/device.vue",
"chars": 588,
"preview": "<template>\n <z-view>\n {{category}}\n <z-spot slot=\"extension\"\n to-view='home'\n :distance='130'\n :an"
},
{
"path": "src/views/devices.vue",
"chars": 1467,
"preview": "<template>\n <z-view>\n <section slot=\"extension\">\n <z-list\n :items=\"devices\"\n :per-page=\"5\">\n "
},
{
"path": "src/views/family.vue",
"chars": 2208,
"preview": "<template>\n<z-view label=\"Leaflet | OpenStreetMap | CartoDB\" ref=\"map\">\n <div slot=\"media\" :id=\"$zircle.getCurrentVie"
},
{
"path": "src/views/home.vue",
"chars": 1652,
"preview": "<template>\n <z-view>\n 11:53 PM\n <br>\n Monday, Oct.\n <br>\n <br>\n <h1>Night mode</h1>\n <br>\n Outs"
},
{
"path": "src/views/living.vue",
"chars": 3997,
"preview": "<template>\n <z-view\n style=\"border-width: 8px\"\n slider\n :progress=\"progress\">\n <span style=\"color: var(--accent-t"
},
{
"path": "src/views/logs.vue",
"chars": 2051,
"preview": "<template>\n <z-view style=\"border-width: 6px\" label=\"Console\">\n <ul>\n <li v-for=\"(log, index) in console\" :key"
},
{
"path": "src/views/rooms.vue",
"chars": 1846,
"preview": "<template>\n <z-view>\n Rooms\n <section slot=\"extension\">\n <z-list\n :items=\"rooms\"\n :per-page=\"3"
},
{
"path": "src/views/scenes.vue",
"chars": 2102,
"preview": "<template>\n <z-view\n label=\"Scenes\"\n slider\n :progress=\"progress\"\n :style=\"styleActive\">\n <h1>{{activeScene}}</h1>"
},
{
"path": "src/views/search.vue",
"chars": 521,
"preview": "<template>\n <z-view>\n <form action=\"search_submit\" method=\"get\" accept-charset=\"utf-8\">\n <input type=\"text\" nam"
},
{
"path": "src/views/settings.vue",
"chars": 1787,
"preview": "<template>\n <z-view label=\"Settings\">\n {{ theme }}\n <div slot=\"extension\">\n <z-spot\n v-for=\"(el, in"
},
{
"path": "src/views/status.vue",
"chars": 1493,
"preview": "<template>\n <z-view label=\"Home status\" style=\"background-color: black\">\n <canvas slot=\"media\" id=\"smoothie-chart\" sty"
},
{
"path": "src/views/tv.vue",
"chars": 1710,
"preview": "<template>\n <z-view>\n <iframe slot=\"media\" width=\"100%\" height=\"100%\" src=\"https://www.youtube.com/embed/aJOTlE1K90k"
}
]
About this extraction
This page contains the full source code of the zircleUI/smarthome-tutorial GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 24 files (27.3 KB), approximately 8.4k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.