Skip to content

Commit b5cfb97

Browse files
committed
icons for media picker display
1 parent 73b30b7 commit b5cfb97

File tree

4 files changed

+128
-35
lines changed

4 files changed

+128
-35
lines changed

packages/media/config/media.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
'min_file_size' => null,
6363
'max_files' => null,
6464
'min_files' => null,
65-
'accepted_file_types' => ['image/*', 'video/*', 'application/pdf'],
65+
'accepted_file_types' => ['image/*', 'video/*', 'application/pdf', 'audio/*', 'text/*', 'application/*',],
6666
'image_resize_mode' => 'cover',
6767
'image_crop_aspect_ratio' => null,
6868
'image_resize_target_width' => null,

packages/media/resources/views/forms/components/media-picker.blade.php

Lines changed: 110 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,94 @@
11
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
2-
<div x-data="{
3-
selectedMedia: {{ json_encode(
4-
$getRecord()?->mediaThroughUsables()?->get()->map(function ($media) {
5-
return [
6-
'id' => $media->id,
7-
'url' => $media->getUrl(),
8-
'file_name' => $media->file_name,
9-
'name' => $media->name
2+
@php
3+
$mimeTypeLabels = [
4+
'application/pdf' => [
5+
'label' => 'PDF',
6+
'icon' => '/vendor/file-icons/pdf.svg'
7+
],
8+
'application/msword' => [
9+
'label' => 'DOC',
10+
'icon' => '/vendor/file-icons/doc.svg'
11+
],
12+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => [
13+
'label' => 'DOCX',
14+
'icon' => '/vendor/file-icons/doc.svg'
15+
],
16+
'application/vnd.ms-excel' => [
17+
'label' => 'XLS',
18+
'icon' => '/vendor/file-icons/xls.svg'
19+
],
20+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => [
21+
'label' => 'XLSX',
22+
'icon' => '/vendor/file-icons/xls.svg'
23+
],
24+
'application/vnd.ms-powerpoint' => [
25+
'label' => 'PPT',
26+
'icon' => '/vendor/file-icons/ppt.svg'
27+
],
28+
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => [
29+
'label' => 'PPTX',
30+
'icon' => '/vendor/file-icons/ppt.svg'
31+
],
32+
'video/mp4' => [
33+
'label' => 'MP4',
34+
'icon' => '/vendor/file-icons/mp4.svg'
35+
],
36+
'video/webm' => [
37+
'label' => 'WEBM',
38+
'icon' => '/vendor/file-icons/mp4.svg'
39+
],
40+
'video/quicktime' => [
41+
'label' => 'MOV',
42+
'icon' => '/vendor/file-icons/mp4.svg'
43+
],
44+
'audio/mpeg' => [
45+
'label' => 'MP3',
46+
'icon' => '/vendor/file-icons/mp3.svg'
47+
],
48+
'audio/wav' => [
49+
'label' => 'WAV',
50+
'icon' => '/vendor/file-icons/mp3.svg'
51+
],
52+
'audio/ogg' => [
53+
'label' => 'OGG',
54+
'icon' => '/vendor/file-icons/mp3.svg'
55+
],
56+
'image/svg+xml' => [
57+
'label' => 'SVG',
58+
'icon' => '/vendor/file-icons/svg.svg'
59+
],
60+
'application/zip' => [
61+
'label' => 'ZIP',
62+
'icon' => '/vendor/file-icons/zip.svg'
63+
],
64+
'application/x-zip-compressed' => [
65+
'label' => 'ZIP',
66+
'icon' => '/vendor/file-icons/zip.svg'
67+
],
68+
'text/plain' => [
69+
'label' => 'TXT',
70+
'icon' => '/vendor/file-icons/txt.svg'
71+
],
72+
'text/csv' => [
73+
'label' => 'CSV',
74+
'icon' => '/vendor/file-icons/csv.svg'
75+
],
1076
];
11-
})->toArray() ?? [],
12-
JSON_UNESCAPED_UNICODE
13-
) }},
77+
@endphp
78+
<div x-data="{
79+
selectedMedia: {{ json_encode($getRecord()?->mediaThroughUsables()?->get()->map(function ($media) {
80+
return [
81+
'id' => $media->id,
82+
'url' => $media->getUrl(),
83+
'file_name' => $media->file_name,
84+
'name' => $media->name,
85+
'mime_type' => $media->mime_type
86+
];
87+
})->toArray() ?? [], JSON_UNESCAPED_UNICODE) }},
88+
mimeTypes: {{ Js::from($mimeTypeLabels) }},
89+
getIconForMimeType(type) {
90+
return this.mimeTypes[type]?.icon || this.mimeTypes['application/pdf'].icon;
91+
},
1492
state: @entangle($getStatePath()),
1593
isMultiple: {{ $field->isMultiple() ? 'true' : 'false' }},
1694
isAvatar: {{ $field->isAvatar() ? 'true' : 'false' }},
@@ -41,28 +119,40 @@
41119
@if ($this instanceof \Filament\Resources\Pages\EditRecord || $this instanceof \Filament\Resources\Pages\CreateRecord)
42120
<x-filament::button color="primary" size="sm" class="w-full flex items-center justify-center space-x-2"
43121
x-on:click="
44-
$dispatch('set-media-picker-model', {
45-
modelId: {{ $getRecord()?->id ?? 0 }},
46-
modelClass: '{{ $getRecord() ? addslashes($getRecord()::class) : addslashes($this->getResource()::getModel()) }}'
47-
});
48-
$dispatch('open-modal', { id: 'mediaPickerModal' });
49-
">
122+
$dispatch('set-media-picker-model', {
123+
modelId: {{ $getRecord()?->id ?? 0 }},
124+
modelClass: '{{ $getRecord() ? addslashes($getRecord()::class) : addslashes($this->getResource()::getModel()) }}'
125+
});
126+
$dispatch('open-modal', { id: 'mediaPickerModal' });
127+
">
50128
<span>{{ __('media::fields.select_media') }}</span>
51129
</x-filament::button>
52130
@endif
53131

54-
55132
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4" x-show="selectedMedia.length > 0">
56133
<template x-for="(media, index) in selectedMedia" :key="media . id">
57134
<div
58135
class="relative group bg-white rounded-lg shadow hover:shadow-md transition-shadow duration-300 overflow-hidden border border-gray-200">
59-
60136
<template x-if="isAvatar">
61137
<x-filament::avatar x-bind:src="media.url" x-bind:alt="media.name" size="w-12 h-12" />
62138
</template>
63139

64140
<template x-if="!isAvatar">
65-
<img :src="media . url" :alt="media . name" class="w-full h-32 object-cover rounded-t-lg" />
141+
<div>
142+
<template x-if="media.mime_type && media.mime_type.startsWith('image/')">
143+
<img :src="media . url" :alt="media . name"
144+
class="w-full h-32 object-cover rounded-t-lg" />
145+
</template>
146+
147+
<template x-if="media.mime_type && !media.mime_type.startsWith('image/')">
148+
<div class="flex flex-col justify-between items-center w-full h-32 mt-3">
149+
<img :src="$el . dataset . baseUrl + getIconForMimeType(media . mime_type)"
150+
data-base-url="{{ asset('') }}" class="w-16 h-16" />
151+
<div class="text-xs text-gray-700 w-full mt-2 overflow-hidden text-ellipsis whitespace-normal break-words px-2"
152+
x-text="media.file_name"></div>
153+
</div>
154+
</template>
155+
</div>
66156
</template>
67157

68158
@if ($this instanceof \Filament\Resources\Pages\EditRecord)
@@ -76,7 +166,6 @@ class="relative group bg-white rounded-lg shadow hover:shadow-md transition-shad
76166
</template>
77167
</div>
78168

79-
80169
<div x-show="selectedMedia.length === 0"
81170
class="border border-dashed border-gray-300 rounded-lg p-4 bg-gray-50 flex items-center justify-center text-sm text-gray-500">
82171
{{ __('media::fields.no_media_selected') }}

packages/media/resources/views/livewire/media-picker-modal.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<div class="flex flex-row gap-4 mb-4">
1919
<x-filament::input.wrapper class="w-1/2">
2020
<x-filament::input type="text" wire:model.live.debounce.500ms="searchQuery"
21-
placeholder="Suche nach Medien..."
21+
placeholder="{{ __('media::fields.search') }}"
2222
class="block w-full border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500" />
2323
</x-filament::input.wrapper>
2424

packages/media/src/Http/Livewire/MediaPickerModal.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,21 @@ public function mount(?int $modelId = null, ?string $modelClass = null): void
6868
$this->modelClass = $modelClass;
6969
$this->modelId = $modelId;
7070

71-
if (! $this->modelClass) {
71+
if (!$this->modelClass) {
7272
$this->modelClass = Media::class;
7373
}
7474

7575
$this->modelClass = str_replace('\\\\', '\\', $this->modelClass);
7676

77-
if (! class_exists($this->modelClass)) {
77+
if (!class_exists($this->modelClass)) {
7878
throw new \Exception(__('media::fields.class_not_found', ['class' => $this->modelClass]));
7979
}
8080

8181
if ($this->modelId) {
8282
$this->model = app($this->modelClass)::find($this->modelId);
8383
}
8484

85-
if (! $this->modelId || ! $this->model) {
85+
if (!$this->modelId || !$this->model) {
8686
$this->modelId = 0;
8787
}
8888
}
@@ -92,13 +92,13 @@ public function form(Form $form): Form
9292
$upload = FileUpload::make(__('files'))
9393
->label(__('media::fields.upload'))
9494
->afterStateUpdated(function ($state) {
95-
if (! $state) {
95+
if (!$state) {
9696
return;
9797
}
9898

9999
$processedFiles = session('processed_files', []);
100100

101-
if (! is_array($state)) {
101+
if (!is_array($state)) {
102102
$model = new Media;
103103
$model->exists = true;
104104

@@ -242,7 +242,7 @@ public function toggleMediaSelection(int $mediaId)
242242
$this->selectedMediaIds[] = $mediaId;
243243
}
244244
} else {
245-
if (! empty($this->selectedMediaIds) && $this->selectedMediaIds[0] === $mediaId) {
245+
if (!empty($this->selectedMediaIds) && $this->selectedMediaIds[0] === $mediaId) {
246246
$this->selectedMediaIds = [];
247247
} else {
248248
$this->selectedMediaIds = [$mediaId];
@@ -281,18 +281,22 @@ public function applySelection()
281281
$selectedMedia = Media::whereIn('id', $this->selectedMediaIds)->get();
282282

283283
if ($selectedMedia->isNotEmpty()) {
284-
if (! $this->multiple) {
284+
if (!$this->multiple) {
285285
$media = $selectedMedia->first();
286286
$this->dispatch('mediaSelected', [
287287
'id' => $media->id,
288288
'url' => $media->getUrl(),
289289
'file_name' => $media->file_name,
290+
'mime_type' => $media->mime_type,
291+
'name' => $media->name
290292
]);
291293
} else {
292-
$selectedMediaData = $selectedMedia->map(fn ($media) => [
294+
$selectedMediaData = $selectedMedia->map(fn($media) => [
293295
'id' => $media->id,
294296
'url' => $media->getUrl(),
295297
'file_name' => $media->file_name,
298+
'mime_type' => $media->mime_type,
299+
'name' => $media->name
296300
])->toArray();
297301

298302
$this->dispatch('mediaSelected', $selectedMediaData);
@@ -340,10 +344,10 @@ public function render()
340344
$media = Media::query()
341345
->when($this->searchQuery, function ($query) {
342346
$query->where(function ($subQuery) {
343-
$subQuery->where('file_name', 'like', '%'.$this->searchQuery.'%')
344-
->orWhere('title', 'like', '%'.$this->searchQuery.'%')
345-
->orWhere('description', 'like', '%'.$this->searchQuery.'%')
346-
->orWhere('alt', 'like', '%'.$this->searchQuery.'%');
347+
$subQuery->where('file_name', 'like', '%' . $this->searchQuery . '%')
348+
->orWhere('title', 'like', '%' . $this->searchQuery . '%')
349+
->orWhere('description', 'like', '%' . $this->searchQuery . '%')
350+
->orWhere('alt', 'like', '%' . $this->searchQuery . '%');
347351
});
348352
})
349353
->when($this->fileTypeFilter, function ($query) {

0 commit comments

Comments
 (0)