Skip to content
This repository was archived by the owner on Dec 9, 2023. It is now read-only.

Commit d7bb4fa

Browse files
committed
Publish develop branch
2 parents f917b53 + 880568a commit d7bb4fa

18 files changed

+1215
-719
lines changed

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
<p>&nbsp;</p>
12
<p align="center">
2-
<a href="https://fretboarder.app" target="_blank" rel="external nofollow noopener noreferrer">
3+
<a href="https://fretboarder.app">
34
<img src="./docs/banner.png" alt="A white icon of a an acoustic guitar and a white text saying Fretboarder over a bright blue background.">
45
</a>
56
</p>
67

7-
<p align="center">Ride your fretboard and take your guitar skills to the next level!&nbsp;&nbsp;🎸&nbsp;&nbsp;🤘</p>
8+
<p align="center">Ride your fretboard and take your guitar skills to the next level! 🤘</p>
89

910
<img src="https://raw.githubusercontent.com/cheap-glitch/fretboarder/main/docs/screenshot.png" alt="A screenshot of the app in usage.">
1011

@@ -16,20 +17,20 @@
1617

1718
## Highlights
1819

19-
🎸&nbsp;&nbsp;&nbsp;**Customize the instrument**
20+
🎸 **Customize the instrument**
2021

2122
Choose between a variety of instruments (from ukulele to 11-string guitar) and
2223
tunings, set the length of the fretboard, and switch between left- and
2324
right-handed fretting.
2425

25-
🎨&nbsp;&nbsp;&nbsp;**Overlay scales and arpeggios**
26+
🍰 **Overlay scales and arpeggios**
2627

2728
The main feature that distinguishes Fretboarder from other similar apps is the
2829
ability to display several sequences of notes on the same fretboard. You can
2930
overlap scales and arpeggios, display their intersections and select specific
3031
positions on the neck.
3132

32-
💻&nbsp;&nbsp;&nbsp;**Use on any device**
33+
💻 **Use on any device**
3334

3435
The UI has been designed to be simple and intuitive, and to work on both desktop
3536
and mobile devices. Dark mode included!
@@ -42,9 +43,7 @@ Contributions are welcomed! See [CONTRIBUTING.md](CONTRIBUTING.md).
4243

4344
## Supporting the app
4445

45-
<a href="https://www.patreon.com/cheap_glitch" target="_blank" rel="external nofollow noopener noreferrer">
46-
<img src="./docs/patreon-badge.png" alt="Become a patron">
47-
</a>
46+
<p><a href="https://www.patreon.com/cheap_glitch"><img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160" alt="Become a patron!"></a></p>
4847

4948
You can support my work on Fretboarder by donating on my [Patreon](https://www.patreon.com/cheap_glitch)
5049
or my [PayPal](https://paypal.me/CheapGlitch) page. Plenty of cool features are coming, such as:

docs/patreon-badge.png

-8.23 KB
Binary file not shown.

package-lock.json

Lines changed: 927 additions & 544 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,20 @@
3232
}
3333
},
3434
"dependencies": {
35-
"@fortawesome/fontawesome-svg-core": "^1.2.28",
36-
"@fortawesome/free-brands-svg-icons": "^5.13.0",
37-
"@fortawesome/vue-fontawesome": "^0.1.9",
35+
"@fortawesome/fontawesome-svg-core": "^1.2.29",
36+
"@fortawesome/free-brands-svg-icons": "^5.13.1",
37+
"@fortawesome/vue-fontawesome": "^0.1.10",
3838
"@popperjs/core": "^2.4.2",
39+
"@vue/composition-api": "^0.6.7",
3940
"core-js": "^3.6.5",
4041
"file-saver": "^2.0.2",
4142
"register-service-worker": "^1.7.1",
4243
"v-click-outside": "^3.0.1",
4344
"vue": "^2.6.11",
4445
"vue-css-modifiers": "^1.0.7",
4546
"vuex": "^3.4.0",
46-
"vuex-pathify": "^1.4.1"
47+
"vuex-pathify": "^1.4.1",
48+
"vuex-plugin-save-state": "^1.0.0"
4749
},
4850
"optionalDependencies": {
4951
"@fortawesome/pro-regular-svg-icons": "^5.13.0",
@@ -53,26 +55,26 @@
5355
"@cheap-glitch/scss-mixins": "^1.0.1",
5456
"@cheap-glitch/scss-reset": "^1.0.0",
5557
"@cheap-glitch/vue-cli-plugin-fontawesome": "^1.0.8",
56-
"@vue/cli-plugin-babel": "^4.4.4",
57-
"@vue/cli-plugin-eslint": "^4.4.4",
58-
"@vue/cli-plugin-unit-mocha": "^4.4.4",
59-
"@vue/cli-plugin-vuex": "^4.4.4",
60-
"@vue/cli-service": "^4.4.4",
58+
"@vue/cli-plugin-babel": "^4.4.6",
59+
"@vue/cli-plugin-eslint": "^4.4.6",
60+
"@vue/cli-plugin-unit-mocha": "^4.4.6",
61+
"@vue/cli-plugin-vuex": "^4.4.6",
62+
"@vue/cli-service": "^4.4.6",
6163
"@vue/test-utils": "^1.0.3",
6264
"babel-eslint": "^10.1.0",
6365
"chai": "^4.2.0",
64-
"eslint": "^7.2.0",
66+
"eslint": "^7.3.1",
6567
"eslint-plugin-smarter-tabs": "^1.1.1",
6668
"eslint-plugin-vue": "^6.2.2",
6769
"fibers": "^5.0.0",
6870
"nodemon": "^2.0.4",
6971
"nyc": "^15.1.0",
7072
"pug": "^3.0.0",
7173
"pug-plain-loader": "^1.0.0",
72-
"sass": "^1.26.8",
74+
"sass": "^1.26.9",
7375
"sass-loader": "^8.0.2",
7476
"sass-mq": "^5.0.1",
75-
"vue-cli-plugin-sitemap": "^2.1.2",
77+
"vue-cli-plugin-sitemap": "^2.2.0",
7678
"vue-template-compiler": "^2.6.11",
7779
"webpack-bundle-analyzer": "^3.8.0"
7880
}

public/index.html

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
<head>
99
<meta charset="utf-8">
1010

11+
<!-- Page title -->
12+
<title><%- VUE_APP_TITLE %></title>
13+
1114
<!-- Emoji favicon -->
1215
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎸</text></svg>">
1316

@@ -33,8 +36,6 @@
3336
<meta name="twitter:title" content="<%- VUE_APP_TITLE %>">
3437
<meta name="twitter:description" content="<%- VUE_APP_DESCRIPTION %>">
3538

36-
<title><%- VUE_APP_TITLE %></title>
37-
3839
<style>
3940
@keyframes spin {
4041
from { transform: rotate( 0deg); }
@@ -57,6 +58,17 @@
5758

5859
animation: spin 800ms ease-in-out infinite;
5960
}
61+
62+
@media (prefers-color-scheme: dark)
63+
{
64+
html, body {
65+
background-color: #171e29;
66+
}
67+
68+
#spinner {
69+
color: #50596c;
70+
}
71+
}
6072
</style>
6173
</head>
6274
<body>

src/App.vue

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,30 @@ div.App#app(:style="colorscheme")
2020
)
2121
h1.logo__text Fretboarder
2222

23-
div.header__settings(v-if="!isMobileDevice")
24-
//- Desktop settings
25-
FretboardTools
23+
//- Settings (desktop)
24+
FretboardTools(v-if="!isMobileDevice")
2625

2726
//- Dark mode toggle switch
28-
button.dark-mode-switch(
27+
//- button.dark-mode-switch(
2928
v-mods="{ isDarkModeOn }"
3029
@click="$store.commit('toggle.isDarkModeOn')"
3130
)
3231
fa-icon.dark-mode-switch__sun(:icon="['fas', 'sun']")
3332
div.dark-mode-switch__toggle
3433
fa-icon.dark-mode-switch__moon(:icon="['fas', 'moon']")
3534
36-
//- Sub-pages links
37-
nav.sublinks(v-if="isMobileDevice")
38-
div.sublinks__item(v-show="subpage == 'fretboard'" @click.left="subpage = 'sequences'"): fa-icon(:icon="['far', 'list-music']")
39-
div.sublinks__item(v-show="subpage == 'fretboard'" @click.left="subpage = 'tools'"): fa-icon(:icon="['far', 'cog']")
40-
div.sublinks__item(v-show="subpage != 'fretboard'" @click.left="subpage = 'fretboard'"): fa-icon(:icon="['far', 'arrow-left']")
35+
//- Sub-pages links (mobile)
36+
nav.header__sublinks(v-if="isMobileDevice")
37+
div.header__sublinks__item(v-show="subpage == 'fretboard'" @click.left="subpage = 'sequences'"): fa-icon(:icon="['far', 'list-music']")
38+
div.header__sublinks__item(v-show="subpage == 'fretboard'" @click.left="subpage = 'tools'"): fa-icon(:icon="['far', 'cog']")
39+
div.header__sublinks__item(v-show="subpage != 'fretboard'" @click.left="subpage = 'fretboard'"): fa-icon(:icon="['far', 'arrow-left']")
4140

4241
//----------------------------------------------------------------------
4342
//- Body
4443
//----------------------------------------------------------------------
4544
div#canvas-wrapper(v-show="false")
4645

47-
//- Tools
46+
//- Settings (mobile)
4847
transition(name="fade"): FretboardTools(v-if="isMobileDevice && subpage == 'tools'")
4948

5049
//- Fretboard
@@ -275,12 +274,6 @@ export default {
275274
}
276275
}
277276
278-
.header__settings {
279-
display: flex;
280-
align-items: center;
281-
@include space-children-h(20px);
282-
}
283-
284277
.logo__icon {
285278
font-size: 18px;
286279
@@ -351,12 +344,12 @@ export default {
351344
}
352345
}
353346
354-
.sublinks {
347+
.header__sublinks {
355348
display: flex;
356349
justify-content: flex-end;
357350
}
358351
359-
.sublinks__item {
352+
.header__sublinks__item {
360353
@include center-content;
361354
@include circle(42px);
362355

src/components/FretboardSequencesItem.vue

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,13 @@ div.FretboardSequencesItem
4545
:style="{ borderColor: color, backgroundColor: color }"
4646
v-mods="{ isOpen }"
4747

48-
@click.left="isOpen = !isOpen"
48+
@click.left="isOpenedByUser = !isOpenedByUser"
4949
)
5050
p {{ infos }}
51-
fa-icon(:icon="['far', isOpen ? 'minus' : 'ellipsis-v']")
51+
fa-icon(
52+
v-show="nbSequences > 1"
53+
:icon="['far', isOpen ? 'minus' : 'ellipsis-v']"
54+
)
5255

5356
//- Settings & tools
5457
transition(name="fade"): div.settings(
@@ -195,7 +198,7 @@ export default {
195198
196199
data() {
197200
return {
198-
isOpen: false,
201+
isOpenedByUser: false,
199202
}
200203
},
201204
@@ -215,6 +218,10 @@ export default {
215218
{
216219
return ('positions' in models[this.model]);
217220
},
221+
isOpen()
222+
{
223+
return this.isOpenedByUser || this.nbSequences == 1;
224+
},
218225
219226
...get([
220227
'isMobileDevice',

src/components/FretboardTools.vue

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ div.FretboardTools
8484
)
8585

8686
//- Possible options for the information displayed on the notes:
87-
* single sequence: none/note name/interval (select menu)
88-
* multiple sequences: none/note name (toggle button)
87+
//- * single sequence: none/note name/interval (select menu)
88+
//- * multiple sequences: none/note name (toggle button)
8989
VSelect(
9090
v-if="displayedSequences.length <= 1"
9191

@@ -102,17 +102,6 @@ div.FretboardTools
102102
@click="$store.commit('fretboard/toggle.isShowingNoteNames')"
103103
)
104104

105-
//- Switch to dark mode
106-
VButton(
107-
v-if="isMobileDevice"
108-
109-
icon="moon"
110-
title="Dark mode"
111-
112-
:is-active="isDarkModeOn"
113-
@click="$store.commit('toggle.isDarkModeOn')"
114-
)
115-
116105
//----------------------------------------------------------------------
117106
//- Export menu
118107
//----------------------------------------------------------------------
@@ -139,6 +128,16 @@ div.FretboardTools
139128
@click=`exportFretboard('${format}')`
140129
)
141130

131+
//----------------------------------------------------------------------
132+
//- Colorscheme setting
133+
//----------------------------------------------------------------------
134+
VTextSelect(
135+
:options="{ light: 'Light mode', dark: 'Dark mode', system: 'System colors' }"
136+
:icon="isDarkModeOn ? 'moon' : 'sun'"
137+
138+
v-model="darkModeSetting"
139+
)
140+
142141
</template>
143142
<!--}}}-->
144143

@@ -172,6 +171,9 @@ export default {
172171
{
173172
return mapObjectToObject(tunings[this.instrument], tuning => tuningsNames[tuning]);
174173
},
174+
...sync([
175+
'darkModeSetting',
176+
]),
175177
...sync('fretboard', [
176178
'instrument',
177179
'tuning',

src/components/VButton.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ export default {
130130
}
131131
132132
.icon,
133-
.icon > *,
134133
.title {
135134
cursor: pointer;
136135

src/components/VSelect.vue

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ div.VSelect
2323
:value="value"
2424
:disabled="isDisabled"
2525

26-
@change="selectOption"
26+
@change="$emit('change', $event.target.value)"
2727
)
2828
//- Grouped options
2929
template(v-if="Array.isArray(options)")
@@ -54,7 +54,9 @@ div.VSelect
5454
<!--{{{ JavaScript -->
5555
<script>
5656
57-
import { formatOrdinalSuffix } from '@/modules/text'
57+
import { toRef } from '@vue/composition-api'
58+
59+
import { useSelectedOptionLabel } from '@/hooks/useSelectedOptionLabel'
5860
5961
export default {
6062
name: 'VSelect',
@@ -83,33 +85,15 @@ export default {
8385
},
8486
},
8587
86-
data() {
88+
setup(props)
89+
{
90+
const { select, selectedOptionLabel } = useSelectedOptionLabel(toRef(props, 'value'), props.labelFormatter);
91+
8792
return {
88-
selectedOptionLabel: '',
93+
select,
94+
selectedOptionLabel,
8995
}
9096
},
91-
92-
watch: {
93-
value: 'updateSelectedOptionLabel',
94-
},
95-
96-
mounted()
97-
{
98-
this.updateSelectedOptionLabel();
99-
},
100-
101-
methods: {
102-
selectOption(event)
103-
{
104-
this.$emit('change', event.target.value);
105-
this.updateSelectedOptionLabel();
106-
},
107-
async updateSelectedOptionLabel()
108-
{
109-
await this.$nextTick();
110-
this.selectedOptionLabel = this.labelFormatter(this.value, formatOrdinalSuffix(this.$refs.select.selectedOptions[0].label));
111-
},
112-
}
11397
}
11498
11599
</script>
@@ -150,7 +134,7 @@ export default {
150134
color: var(--color--text);
151135
background-color: var(--color--bg--accent);
152136
153-
.select:not(:focus):not(:disabled):hover + & {
137+
.select:not(:disabled):hover + & {
154138
border-color: var(--color--hover);
155139
background-color: var(--color--bg--highlight);
156140
}

0 commit comments

Comments
 (0)