/
AvatarModal.vue
157 lines (138 loc) · 6.43 KB
/
AvatarModal.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<template>
<div class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div ref="modal" class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body pb-0">
<file-pond
ref="pond"
v-if="isReadyToAcceptUploads"
name="avatarPond"
max-files="1"
:max-file-size="settings.maxUpload"
:icon-remove="getRemoveIcon"
:icon-retry="getRetryIcon"
:label-idle="getPlaceholderLabel"
accepted-file-types="image/*"
:server="getServerOptions"
:allow-multiple="false"
@processfile="processedFromFilePond"
@removefile="removedFromFilePond"
/>
<div v-if="!isReadyToAcceptUploads" class="selected-image">
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
@click.prevent="clearAndResetComponent"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" class="icon-trash">
<path
class="fill-light-gray"
d="M5 5h14l-.89 15.12a2 2 0 0 1-2 1.88H7.9a2 2 0 0 1-2-1.88L5 5zm5 5a1 1 0 0 0-1 1v6a1 1 0 0 0 2 0v-6a1 1 0 0 0-1-1zm4 0a1 1 0 0 0-1 1v6a1 1 0 0 0 2 0v-6a1 1 0 0 0-1-1z"
/>
<path
class="fill-light-gray"
d="M8.59 4l1.7-1.7A1 1 0 0 1 11 2h2a1 1 0 0 1 .7.3L15.42 4H19a1 1 0 0 1 0 2H5a1 1 0 1 1 0-2h3.59z"
/>
</svg>
</button>
<img :src="selectedImageUrl" class="w-100 rounded mb-3" />
</div>
</div>
<div class="modal-footer">
<button
class="btn btn-link btn-block text-muted font-weight-bold text-decoration-none"
data-dismiss="modal"
@click="save"
>
{{ trans.save }}
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapGetters, mapState } from 'vuex';
import isEmpty from 'lodash/isEmpty';
import vueFilePond from 'vue-filepond';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
import 'filepond/dist/filepond.min.css';
import FilePondPluginFileValidateSize from 'filepond-plugin-file-validate-size';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginImageExifOrientation from 'filepond-plugin-image-exif-orientation';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginImageValidateSize from 'filepond-plugin-image-validate-size';
const FilePond = vueFilePond(
FilePondPluginFileValidateType,
FilePondPluginImagePreview,
FilePondPluginImageValidateSize,
FilePondPluginFileValidateSize,
FilePondPluginImageExifOrientation
);
export default {
name: 'avatar-modal',
components: {
FilePond,
},
props: {
user: {
type: Object,
required: true,
},
},
data() {
return {
selectedImageUrl: null,
isReadyToAcceptUploads: false,
};
},
computed: {
...mapState(['settings']),
...mapGetters({
trans: 'settings/trans',
}),
getServerOptions() {
return {
url: `/${this.settings.path}/api/uploads`,
headers: {
'X-CSRF-TOKEN': document.head.querySelector('meta[name="csrf-token"]').content,
},
};
},
getRetryIcon() {
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="icon-refresh" width="26"><circle style="fill:none" cx="12" cy="12" r="10"/><path style="fill:white" d="M8.52 7.11a5.98 5.98 0 0 1 8.98 2.5 1 1 0 1 1-1.83.8 4 4 0 0 0-5.7-1.86l.74.74A1 1 0 0 1 10 11H7a1 1 0 0 1-1-1V7a1 1 0 0 1 1.7-.7l.82.81zm5.51 8.34l-.74-.74A1 1 0 0 1 14 13h3a1 1 0 0 1 1 1v3a1 1 0 0 1-1.7.7l-.82-.81A5.98 5.98 0 0 1 6.5 14.4a1 1 0 1 1 1.83-.8 4 4 0 0 0 5.7 1.85z"/></svg>';
},
getRemoveIcon() {
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="26" class="icon-close-circle"><circle style="fill:none" cx="12" cy="12" r="10"/><path style="fill:white" d="M13.41 12l2.83 2.83a1 1 0 0 1-1.41 1.41L12 13.41l-2.83 2.83a1 1 0 1 1-1.41-1.41L10.59 12 7.76 9.17a1 1 0 0 1 1.41-1.41L12 10.59l2.83-2.83a1 1 0 0 1 1.41 1.41L13.41 12z"/></svg>';
},
getPlaceholderLabel() {
return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="35" class="icon-cloud-upload mr-3"><path class="fill-dark-gray" d="M18 14.97c0-.76-.3-1.51-.88-2.1l-3-3a3 3 0 0 0-4.24 0l-3 3A3 3 0 0 0 6 15a4 4 0 0 1-.99-7.88 5.5 5.5 0 0 1 10.86-.82A4.49 4.49 0 0 1 22 10.5a4.5 4.5 0 0 1-4 4.47z"/><path class="fill-dark-gray" d="M11 14.41V21a1 1 0 0 0 2 0v-6.59l1.3 1.3a1 1 0 0 0 1.4-1.42l-3-3a1 1 0 0 0-1.4 0l-3 3a1 1 0 0 0 1.4 1.42l1.3-1.3z"/></svg> Drop files or click here to upload';
},
},
mounted() {
this.selectedImageUrl = this.user.avatar;
this.isReadyToAcceptUploads = isEmpty(this.selectedImageUrl);
},
methods: {
processedFromFilePond() {
this.isReadyToAcceptUploads = true;
this.user.avatar = document.getElementsByName('avatarPond')[0].value;
},
removedFromFilePond() {
this.isReadyToAcceptUploads = true;
this.user.avatar = this.user.default_avatar;
},
clearAndResetComponent() {
this.user.avatar = this.selectedImageUrl;
this.selectedImageUrl = null;
this.isReadyToAcceptUploads = true;
},
save() {
this.$refs.modal.hide;
this.$emit('update');
},
},
};
</script>