Skip to content

Commit 1468cb0

Browse files
authored
Merge pull request #48 from torrust/develop
release version `2.0.0`
2 parents ed72a06 + 2e89fe8 commit 1468cb0

20 files changed

+7029
-1512
lines changed

package-lock.json

+6,564-1,377
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "torrust-index-frontend",
3-
"version": "1.0.0",
3+
"version": "2.0.0",
44
"description": "This repository serves as the frontend for the Torrust Index project.",
55
"author": "Mick van Dijke <mick@dutchbits.nl>",
66
"license": "AGPL-3.0",
@@ -21,7 +21,7 @@
2121
"axios": "^0.21.3",
2222
"core-js": "^3.6.5",
2323
"markdown-it": "^12.3.2",
24-
"markdown-it-vue": "^1.1.6",
24+
"markdown-it-vue": "^1.1.7",
2525
"v-click-outside": "^3.1.2",
2626
"vue": "^2.6.11",
2727
"vue-notification": "^1.3.20",
@@ -41,7 +41,7 @@
4141
"postcss": "^8.4.5",
4242
"prettier": "2.5.1",
4343
"tailwindcss": "^3.0.15",
44-
"vite": "^2.5.4",
44+
"vite": "^2.9.13",
4545
"vite-plugin-vue2": "^1.9.2",
4646
"vue-template-compiler": "^2.6.14"
4747
},

src/App.vue

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@ export default {
1616
name: 'App',
1717
components: {Toast, Navbar},
1818
beforeMount() {
19-
this.$store.dispatch('getSiteName')
19+
this.$store.dispatch('getPublicSettings');
20+
this.$store.dispatch('getSiteName');
21+
this.$store.dispatch('renewToken');
2022
},
2123
watch:{
2224
$route (to, from){
25+
this.$store.dispatch('getPublicSettings');
2326
this.$store.dispatch('getCategories');
2427
this.$store.dispatch('getSiteName');
28+
this.$store.dispatch('renewToken');
2529
}
2630
}
2731
}

src/components/PageSize.vue

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<template>
2+
<div class="relative inline-block text-left spaced" v-click-outside="() => (dropdownOpened = false)">
3+
<button class="filter relative" @click="dropdownOpened = !dropdownOpened">
4+
<AdjustmentsIcon size="16" class="mr-1 opacity-50" />
5+
Page Size
6+
</button>
7+
<div class="origin-top-left absolute left-0 mt-2 z-10" :class="{hidden: !dropdownOpened}">
8+
<div class="py-2 px-2 w-48 flex flex-col bg-slate-800 text-sm rounded-md shadow-lg">
9+
<ul v-if="$route.name === 'Browse Torrents'" id="category-filters" class="">
10+
<li v-for="size in pageSizeList"
11+
@click="updateSize(size)"
12+
class="cursor-pointer text-slate-400 hover:text-white"
13+
:key="size">
14+
<span class="">{{ size }}</span>
15+
</li>
16+
</ul>
17+
</div>
18+
</div>
19+
</div>
20+
</template>
21+
22+
<script>
23+
import {UserIcon} from "@vue-hero-icons/outline";
24+
import { AdjustmentsIcon } from '@vue-hero-icons/solid'
25+
import {mapState} from "vuex";
26+
27+
export default {
28+
name: "ChangePageSize",
29+
components: {UserIcon, AdjustmentsIcon},
30+
props: {
31+
updatePageSize: {
32+
type: Function,
33+
required: true
34+
},
35+
pageSizeList: {
36+
type: Array,
37+
required: true
38+
}
39+
},
40+
data: () => ({
41+
dropdownOpened: false
42+
}),
43+
computed: {
44+
...mapState({
45+
user: state => state.auth.user
46+
})
47+
},
48+
methods: {
49+
updateSize(size) {
50+
this.updatePageSize(size);
51+
this.dropdownOpened = false;
52+
}
53+
}
54+
}
55+
</script>
56+
57+
<style scoped>
58+
.filter {
59+
@apply px-3 py-1.5 text-slate-400 text-sm border border-slate-800 rounded-md flex items-center relative cursor-pointer transition duration-200 hover:text-slate-200 hover:border-slate-200;
60+
}
61+
62+
.regular-checkbox {
63+
@apply text-sky-400;
64+
-webkit-appearance: none;
65+
background-color: rgba(0, 0, 0, .1);
66+
border: none;
67+
box-shadow: 0 1px 2px rgba(0,0,0,0.05), inset 0px -15px 10px -12px rgba(0,0,0,0.05);
68+
padding: 9px;
69+
border-radius: 3px;
70+
display: inline-block;
71+
position: relative;
72+
}
73+
74+
.spaced {
75+
margin-left: 10px;
76+
}
77+
78+
#category-filters li {
79+
@apply px-2 py-1 flex flex-row justify-between;
80+
}
81+
82+
#category-filters li input {
83+
@apply text-left
84+
}
85+
</style>

src/components/Pagination.vue

+37-36
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
<template>
2-
<!-- This example requires Tailwind CSS v2.0+ -->
32
<div class="py-6 flex items-center justify-between">
43
<div class="flex-1 flex items-center sm:justify-between justify-end">
54
<div class="hidden sm:block">
65
<p class="text-sm text-slate-400">
76
Showing
87
<span class="font-medium">{{ (currentPage * pageSize) - pageSize }}</span>
98
to
10-
<span class="font-medium">{{ currentPage * pageSize }}</span>
9+
<span class="font-medium">{{ Math.min(currentPage * pageSize, totalResults) }}</span>
1110
of
1211
<span class="font-medium">{{ totalResults }}</span>
1312
results
@@ -38,33 +37,52 @@
3837
</svg>
3938
</button>
4039

41-
<template v-if="currentPage > 4">
42-
<button
43-
@click="goToFirstPage"
44-
class="page-button">
45-
1
40+
<!--show all page buttons-->
41+
<template v-if="totalPages < 7">
42+
<button v-for="i in totalPages" :key="i"
43+
@click="goToPage(i)"
44+
:disabled="i === currentPage"
45+
class="page-button">
46+
{{ i }}
47+
</button>
48+
</template>
49+
50+
<template v-else-if="currentPage <= 4">
51+
<button v-for="i in 5" :key="i"
52+
@click="goToPage(i)"
53+
:disabled="i === currentPage"
54+
class="page-button">
55+
{{ i }}
4656
</button>
47-
<span
57+
<span v-if="totalPages > 7"
4858
class="page-button">
4959
...
5060
</span>
5161
</template>
52-
<!-- <button v-else v-for="i in 5" :key="i" v-show="i < totalPages"-->
53-
<!-- @click="goToPage(i)"-->
54-
<!-- :disabled="i === currentPage"-->
55-
<!-- class="page-button">-->
56-
<!-- {{ i }}-->
57-
<!-- </button>-->
5862

59-
<template v-if="currentPage > 4 && currentPage < totalPages-3">
63+
<template v-else-if="currentPage > totalPages - 4">
64+
<span v-if="totalPages > 7"
65+
class="page-button">
66+
...
67+
</span>
68+
<button v-for="i in 5" :key="totalPages - 5 + i"
69+
@click="goToPage(totalPages - 5 + i)"
70+
:disabled="totalPages - 5 + i === currentPage"
71+
class="page-button">
72+
{{ totalPages - 5 + i }}
73+
</button>
74+
</template>
75+
76+
<template v-else>
77+
<span class="page-button">
78+
...
79+
</span>
6080
<button v-for="i in 2" :key="currentPage - 3 + i"
6181
@click="goToPage(currentPage - 3 + i)"
6282
class="page-button">
6383
{{ currentPage - 3 + i }}
6484
</button>
65-
<button
66-
:key="currentPage"
67-
disabled
85+
<button disabled
6886
class="page-button">
6987
{{ currentPage }}
7088
</button>
@@ -73,26 +91,9 @@
7391
class="page-button">
7492
{{ currentPage + i }}
7593
</button>
76-
</template>
77-
78-
<template v-if="currentPage < totalPages-3">
79-
<span
80-
class="page-button">
94+
<span class="page-button">
8195
...
8296
</span>
83-
<button
84-
@click="goToLastPage"
85-
class="page-button">
86-
{{ totalPages }}
87-
</button>
88-
</template>
89-
<template v-else>
90-
<button v-for="i in 5" :key="totalPages-5+i" v-show="totalPages-5+i > 0"
91-
@click="goToPage(totalPages-5+i)"
92-
:disabled="totalPages-5+i === currentPage"
93-
class="page-button">
94-
{{ totalPages-5+i }}
95-
</button>
9697
</template>
9798

9899
<button

src/components/SelectComponent.vue

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<template>
2+
<div v-click-outside="() => (dropdownOpened = false)">
3+
<button
4+
type="button"
5+
class="relative py-2 pr-10 pl-3 w-full text-left bg-slate-800/50 text-slate-400 rounded-md border border-slate-700 cursor-pointer focus:outline-none focus:ring-1 focus:border-sky-500 sm:text-sm"
6+
@click="dropdownOpened = !dropdownOpened"
7+
>
8+
<span class="block truncate capitalize">{{ selected || 'Select a category...' }}</span>
9+
<span class="flex absolute inset-y-0 right-0 items-center pr-2 pointer-events-none">
10+
<SelectorIcon class="w-5 h-5 text-gray-400"/>
11+
</span>
12+
</button>
13+
14+
<transition
15+
leave-active-class="transition duration-100 ease-in"
16+
leave-from-class="opacity-100"
17+
leave-to-class="opacity-0"
18+
>
19+
<ul
20+
v-if="dropdownOpened"
21+
class="overflow-auto absolute z-10 py-1 mt-1 w-full max-h-60 text-base bg-slate-800 rounded-md ring-1 ring-black ring-opacity-5 shadow-lg focus:outline-none sm:text-sm"
22+
tabindex="-1" role="listbox"
23+
>
24+
<li class="relative py-2 pr-9 pl-3 text-slate-200 cursor-pointer select-none hover:text-sky-400 hover:bg-primary-600"
25+
role="option"
26+
v-for="(option, index) in options"
27+
:key="index"
28+
@click="select(option.name)"
29+
>
30+
<span
31+
class="block truncate capitalize"
32+
:class="[selected === option.name ? 'font-semibold' : 'font-normal']"
33+
>
34+
{{ option.name }}
35+
</span>
36+
37+
<span
38+
v-if="selected === option.name"
39+
class="flex absolute inset-y-0 right-0 items-center pr-4 text-primary-600 row-icon"
40+
>
41+
<CheckIcon class="w-5 h-5"/>
42+
</span>
43+
</li>
44+
</ul>
45+
</transition>
46+
</div>
47+
</template>
48+
49+
<script>
50+
import {CheckIcon, SelectorIcon} from "@vue-hero-icons/solid";
51+
52+
export default {
53+
name: "SelectComponent",
54+
components: {CheckIcon, SelectorIcon},
55+
props: ['options', 'selected'],
56+
emits: ['update'],
57+
data: () => ({
58+
dropdownOpened: false,
59+
}),
60+
methods: {
61+
select(val) {
62+
this.dropdownOpened = false;
63+
this.$emit('update', val);
64+
}
65+
}
66+
}
67+
</script>
68+
69+
<style scoped>
70+
li:hover .row-icon {
71+
@apply text-white;
72+
}
73+
</style>

src/components/TorrentList.vue

+5-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
{{ torrent.leechers }}
5050
</td>
5151
<td>
52-
{{ timeSince(torrent.upload_date) }} ago
52+
{{ timeSince(torrent.date_uploaded) }} ago
5353
</td>
5454
<td>
5555
{{ fileSize(torrent.file_size) }}
@@ -68,6 +68,7 @@
6868

6969
<script>
7070
import { SortAscendingIcon, SortDescendingIcon } from "@vue-hero-icons/outline"
71+
import {mapState} from "vuex";
7172
7273
export default {
7374
name: "TorrentList",
@@ -90,6 +91,9 @@ export default {
9091
'size',
9192
]
9293
}),
94+
computed: {
95+
...mapState(['categories']),
96+
},
9397
methods: {
9498
changeSort(sort) {
9599
let direction = 'ASC';
@@ -104,7 +108,6 @@ export default {
104108
direction = 'DESC'
105109
}
106110
this.updateSorting({name: sort, direction});
107-
//this.$emit('update:sorting', sort);
108111
}
109112
}
110113
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<button @click="click" :disabled="disabled">
3+
<TrashIcon class="h-5 w-5 opacity-50" />
4+
<span class="ml-1">discard changes</span>
5+
</button>
6+
</template>
7+
8+
<script>
9+
import { TrashIcon } from "@vue-hero-icons/outline";
10+
11+
export default {
12+
name: "CancelButton",
13+
components: { TrashIcon },
14+
props: ['click', 'disabled']
15+
}
16+
</script>
17+
18+
<style scoped>
19+
button {
20+
@apply py-1.5 px-3 flex items-center bg-sky-200 text-xs text-sky-600 font-semibold rounded-md transition duration-200 hover:text-sky-500 disabled:opacity-50;
21+
}
22+
</style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<button @click="click" :disabled="disabled">
3+
<CheckIcon class="h-5 w-5 opacity-50" />
4+
<span class="ml-1">save changes</span>
5+
</button>
6+
</template>
7+
8+
<script>
9+
import { CheckIcon } from "@vue-hero-icons/outline";
10+
11+
export default {
12+
name: "SaveButton",
13+
components: { CheckIcon },
14+
props: ['click', 'disabled']
15+
}
16+
</script>
17+
18+
<style scoped>
19+
button {
20+
@apply py-1.5 px-3 flex items-center text-xs text-white font-semibold bg-sky-600 rounded-md transition duration-200 hover:bg-sky-500 disabled:opacity-50;
21+
}
22+
</style>

0 commit comments

Comments
 (0)