Skip to content
Snippets Groups Projects
Table.vue 5.61 KiB
Newer Older
onny's avatar
onny committed
<!--
  - @copyright Copyright (c) 2020 Jonas Heinrich
  -
  - @author Jonas Heinrich <onny@project-insanity.org>
  -
  - @license GNU AGPL version 3 or any later version
  -
  - This program is free software: you can redistribute it and/or modify
  - it under the terms of the GNU Affero General Public License as
  - published by the Free Software Foundation, either version 3 of the
  - License, or (at your option) any later version.
  -
  - This program is distributed in the hope that it will be useful,
  - but WITHOUT ANY WARRANTY; without even the implied warranty of
  - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  - GNU Affero General Public License for more details.
  -
  - You should have received a copy of the GNU Affero General Public License
  - along with this program. If not, see <http://www.gnu.org/licenses/>.
  -
  -->

<template>
	<table>
		<thead>
			<tr>
				<th class="iconColumn" />
				<th class="nameColumn">
					{{ t('radio', 'Name') }}
				</th>
				<th class="actionColumn" />
			</tr>
		</thead>
		<tbody>
			<template v-if="!isFolder">
				<tr
					v-for="(station, idx) in stationData"
					:key="idx"
					:class="{ selected: idx === activeItem}">
					<td @click="doPlay(idx, station)">
						<blur-hash-image
							class="stationIcon"
							width="32"
							height="32"
							:hash="station.blurHash"
							:src="station.favicon" />
						<span :class="{ 'icon-starred': favorites.flat().includes(station.stationuuid) }" />
					</td>
					<td class="nameColumn" @click="doPlay(idx, station)">
						<span class="innernametext">
							{{ station.name }}
						</span>
					</td>
					<td class="actionColumn">
						<Actions>
							<ActionButton
								v-if="!favorites.flat().includes(station.stationuuid)"
								icon="icon-star"
								:close-after-click="true"
								@click="doFavor(idx, station)">
								{{ t('radio', 'Add to favorites') }}
							</ActionButton>
							<ActionButton
								v-if="favorites.flat().includes(station.stationuuid)"
								icon="icon-star"
								:close-after-click="true"
								@click="doFavor(idx, station)">
								{{ t('radio', 'Remove from favorites') }}
							</ActionButton>
							<ActionButton
								icon="icon-info"
								:close-after-click="true"
								@click="toggleSidebar(station)">
								{{ t('radio', 'Details') }}
							</ActionButton>
						</Actions>
					</td>
				</tr>
			</template>
			<template v-if="isFolder">
				<tr
					v-for="(station, idx) in stationData"
					:key="idx"
					@click="changeRoute(station.path)">
					<td>
						<span class="icon-folder" />
					</td>
					<td class="nameColumn">
						<span class="innernametext">
							{{ station.name }}
						</span>
					</td>
					<td class="actionColumn" />
				</tr>
			</template>
		</tbody>
	</table>
</template>

<script>
import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'

export default {
	name: 'Table',
	components: {
		Actions,
		ActionButton,
	},
	props: {
		favorites: {
			type: Array,
			default() { return [] },
		},
		stationData: {
			type: Array,
			default() { return [] },
		},
	},
	data: () => ({
		activeItem: null,
	}),
	computed: {
		isFolder() {
			if (this.stationData[0]) {
				if (this.stationData[0].type === 'folder') {
					return true
				}
			}
			return false
		},
	},
	methods: {
		doPlay(idx, station) {
			this.activeItem = idx
			this.$emit('doPlay', station)
		},
		doFavor(idx, station) {
			this.$emit('doFavor', station)
		},
		toggleSidebar(station) {
			this.$emit('toggleSidebar', station)
		},
		changeRoute(path) {
			this.$router.push({ path })
		},
	},
}
</script>

<style lang="scss">

/* Workaround wrong positioning
   actions popover menu
	  https://github.com/nextcloud/nextcloud-vue/issues/1384 */
body {
	min-height: 100%;
	height: auto;
}

table {
	width: 100%;
	min-width: 250px;
	table-layout:fixed;
	position: relative;

	thead {
		background-color: var(--color-main-background-translucent);
		z-index: 60;
		position: sticky;
		top: 50px;

		th {
			border-bottom: 1px solid var(--color-border);
			padding: 15px;
			height: 50px;
		}

		th, th a {
			color: var(--color-text-maxcontrast);
		}

		th.iconColumn {
			padding: 0px;
			width: 72px;
		}

		th.nameColumn {
			width: 100%;
		}

		th.actionColumn {
			width: 72px;
		}

	}

	tbody {

		td {
			padding: 0 15px;
			font-style: normal;
			background-position: 8px center;
			background-repeat: no-repeat;
			border-bottom: 1px solid var(--color-border);
			cursor: pointer;

			span.icon-folder {
				display: block;
				background-size: cover;
				width: 30px;
				height: 30px;
			}
		}

		tr {
			height: 51px;
			background-color: var(--color-background-light);
			transition: opacity 500ms ease 0s;

			tr:hover, tr:focus, tr.mouseOver td {
				background-color: var(--color-background-hover);
			}

		}

		tr td * {
			cursor: pointer;
		}

		tr.selected {
			background-color: var(--color-primary-light);
		}

		tr td:first-child {
			padding-left: 40px;
			width: 32px;
			padding-right: 0px;
		}

		td.nameColumn {
			white-space: nowrap;
			overflow: hidden;
			text-overflow: ellipsis;
			padding-right: 0px;
		}

		td.nameColumn .innernametext {
			color: var(--color-main-text);
			position: relative;
			vertical-align: top;
			user-select: none;
			cursor: pointer;
		}

		.icon-starred {
			background-image: var(--icon-star-dark-fc0);
			background-size: 16px 16px;
			background-repeat: no-repeat;
			background-position: center;
			min-width: 16px;
			min-height: 16px;
			right: -7px;
			top: -38px;
			margin-bottom: -38px;
			float: right;
			position: relative;
			pointer-events: none;
		}

	}

}

</style>