Commit | Line | Data |
---|---|---|
604b951e BA |
1 | <template lang="pug"> |
2 | main | |
3 | input#modalNews.modal(type="checkbox") | |
910d631b BA |
4 | div#newnewsDiv( |
5 | role="dialog" | |
6 | data-checkbox="modalNews" | |
7 | ) | |
23e1fa07 | 8 | .card#writeNews |
604b951e BA |
9 | label.modal-close(for="modalNews") |
10 | textarea#newsContent( | |
11 | v-model="curnews.content" | |
12 | :placeholder="st.tr['News go here']" | |
13 | @input="adjustHeight" | |
14 | ) | |
15 | button(@click="sendNews()") {{ st.tr["Send"] }} | |
16 | #dialog.text-center {{ st.tr[infoMsg] }} | |
17 | .row | |
18 | .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 | |
23e1fa07 | 19 | button#writeNewsBtn( |
604b951e BA |
20 | v-if="devs.includes(st.user.id)" |
21 | @click="showModalNews" | |
22 | ) | |
23 | | {{ st.tr["Write news"] }} | |
910d631b BA |
24 | .news( |
25 | v-for="n,idx in newsList" | |
26 | :class="{margintop:idx>0}" | |
27 | ) | |
bd76b456 | 28 | span.ndt {{ formatDatetime(n.added) }} |
604b951e BA |
29 | div(v-if="devs.includes(st.user.id)") |
30 | button(@click="editNews(n)") {{ st.tr["Edit"] }} | |
31 | button(@click="deleteNews(n)") {{ st.tr["Delete"] }} | |
bd76b456 | 32 | p(v-html="parseHtml(n.content)") |
910d631b BA |
33 | button( |
34 | v-if="hasMore" | |
35 | @click="loadMore()" | |
36 | ) | |
604b951e BA |
37 | | {{ st.tr["Load more"] }} |
38 | </template> | |
39 | ||
40 | <script> | |
41 | import { store } from "@/store"; | |
42 | import { ajax } from "@/utils/ajax"; | |
43 | import { getDate, getTime } from "@/utils/datetime"; | |
44 | import { processModalClick } from "@/utils/modalClick"; | |
45 | export default { | |
46 | name: "my-news", | |
47 | data: function() { | |
48 | return { | |
49 | devs: [1], //for now the only dev is me | |
50 | st: store.state, | |
51 | cursor: 0, //ID of last showed news | |
52 | hasMore: true, //a priori there could be more news to load | |
6808d7a1 | 53 | curnews: { id: 0, content: "" }, |
604b951e | 54 | newsList: [], |
6808d7a1 | 55 | infoMsg: "" |
604b951e BA |
56 | }; |
57 | }, | |
58 | created: function() { | |
6808d7a1 BA |
59 | ajax("/news", "GET", { cursor: this.cursor }, res => { |
60 | this.newsList = res.newsList.sort((n1, n2) => n1.added - n2.added); | |
604b951e | 61 | const L = res.newsList.length; |
6808d7a1 | 62 | if (L > 0) this.cursor = this.newsList[0].id; |
604b951e BA |
63 | }); |
64 | }, | |
65 | mounted: function() { | |
6808d7a1 BA |
66 | document |
67 | .getElementById("newnewsDiv") | |
68 | .addEventListener("click", processModalClick); | |
604b951e BA |
69 | }, |
70 | methods: { | |
71 | formatDatetime: function(dt) { | |
72 | const dtObj = new Date(dt); | |
bd76b456 BA |
73 | const timePart = getTime(dtObj); |
74 | // Show minutes but not seconds: | |
6808d7a1 BA |
75 | return ( |
76 | getDate(dtObj) + " " + timePart.substr(0, timePart.lastIndexOf(":")) | |
77 | ); | |
604b951e BA |
78 | }, |
79 | parseHtml: function(txt) { | |
80 | return !txt.match(/<[/a-zA-Z]+>/) | |
81 | ? txt.replace(/\n/g, "<br/>") //no HTML tag | |
82 | : txt; | |
83 | }, | |
84 | adjustHeight: function() { | |
85 | const newsContent = document.getElementById("newsContent"); | |
86 | // https://stackoverflow.com/questions/995168/textarea-to-resize-based-on-content-length | |
87 | newsContent.style.height = "1px"; | |
6808d7a1 | 88 | newsContent.style.height = 10 + newsContent.scrollHeight + "px"; |
604b951e BA |
89 | }, |
90 | resetCurnews: function() { | |
91 | this.curnews.id = 0; | |
92 | this.curnews.content = ""; | |
93 | // No need for added and uid fields: never updated | |
94 | }, | |
95 | showModalNews: function() { | |
96 | this.resetCurnews(); | |
6808d7a1 | 97 | window.doClick("modalNews"); |
604b951e BA |
98 | }, |
99 | sendNews: function() { | |
100 | const edit = this.curnews.id > 0; | |
101 | this.infoMsg = "Processing... Please wait"; | |
6808d7a1 BA |
102 | ajax("/news", edit ? "PUT" : "POST", { news: this.curnews }, res => { |
103 | if (edit) { | |
104 | let n = this.newsList.find(n => n.id == this.curnews.id); | |
105 | if (n) n.content = this.curnews.content; | |
106 | } else { | |
107 | const newNews = { | |
108 | content: this.curnews.content, | |
109 | added: Date.now(), | |
110 | uid: this.st.user.id, | |
111 | id: res.id | |
112 | }; | |
113 | this.newsList = [newNews].concat(this.newsList); | |
604b951e | 114 | } |
6808d7a1 BA |
115 | document.getElementById("modalNews").checked = false; |
116 | this.infoMsg = ""; | |
117 | this.resetCurnews(); | |
118 | }); | |
604b951e BA |
119 | }, |
120 | editNews: function(n) { | |
121 | this.curnews.content = n.content; | |
122 | this.curnews.id = n.id; | |
123 | // No need for added and uid fields: never updated | |
6808d7a1 | 124 | window.doClick("modalNews"); |
604b951e BA |
125 | }, |
126 | deleteNews: function(n) { | |
6808d7a1 | 127 | if (confirm(this.st.tr["Are you sure?"])) { |
604b951e | 128 | this.infoMsg = "Processing... Please wait"; |
6808d7a1 | 129 | ajax("/news", "DELETE", { id: n.id }, () => { |
604b951e BA |
130 | const nIdx = this.newsList.findIndex(nw => nw.id == n.id); |
131 | this.newsList.splice(nIdx, 1); | |
132 | this.infoMsg = ""; | |
133 | document.getElementById("modalNews").checked = false; | |
134 | }); | |
135 | } | |
136 | }, | |
137 | loadMore: function() { | |
6808d7a1 BA |
138 | ajax("/news", "GET", { cursor: this.cursor }, res => { |
139 | if (res.newsList.length > 0) { | |
604b951e BA |
140 | this.newsList = this.newsList.concat(res.newsList); |
141 | const L = res.newsList.length; | |
6808d7a1 BA |
142 | if (L > 0) this.cursor = res.newsList[L - 1].id; |
143 | } else this.hasMore = false; | |
604b951e | 144 | }); |
6808d7a1 BA |
145 | } |
146 | } | |
604b951e BA |
147 | }; |
148 | </script> | |
149 | ||
150 | <style lang="sass" scoped> | |
151 | [type="checkbox"].modal+div .card | |
152 | max-width: 767px | |
153 | max-height: 100% | |
910d631b | 154 | |
604b951e | 155 | textarea#newsContent |
bd76b456 | 156 | margin: 0 |
604b951e BA |
157 | width: 100% |
158 | min-height: 200px | |
159 | max-height: 100% | |
910d631b | 160 | |
604b951e BA |
161 | #dialog |
162 | padding: 5px | |
163 | color: blue | |
910d631b | 164 | |
23e1fa07 BA |
165 | #writeNews |
166 | padding-top: 50px | |
167 | ||
168 | button#writeNewsBtn | |
0c76fa56 BA |
169 | margin-top: 0 |
170 | margin-bottom: 0 | |
910d631b | 171 | |
bd76b456 BA |
172 | span.ndt |
173 | color: darkblue | |
feae89d3 | 174 | padding: 0 5px 0 var(--universal-margin) |
910d631b | 175 | |
feae89d3 BA |
176 | .news |
177 | padding-top: 10px | |
bd76b456 BA |
178 | & > div |
179 | display: inline-block | |
910d631b BA |
180 | |
181 | .margintop | |
182 | margin-top: 25px | |
183 | border-top: 1px solid grey | |
bd76b456 BA |
184 | @media screen and (max-width: 767px) |
185 | .margintop | |
186 | margin-top: 10px | |
604b951e | 187 | </style> |