vines-services 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +19 -0
- data/README +40 -0
- data/Rakefile +130 -0
- data/bin/vines-services +95 -0
- data/conf/config.rb +25 -0
- data/lib/vines/services/command/init.rb +209 -0
- data/lib/vines/services/command/restart.rb +14 -0
- data/lib/vines/services/command/start.rb +30 -0
- data/lib/vines/services/command/stop.rb +20 -0
- data/lib/vines/services/command/views.rb +26 -0
- data/lib/vines/services/component.rb +26 -0
- data/lib/vines/services/config.rb +105 -0
- data/lib/vines/services/connection.rb +120 -0
- data/lib/vines/services/controller/attributes_controller.rb +19 -0
- data/lib/vines/services/controller/base_controller.rb +99 -0
- data/lib/vines/services/controller/disco_info_controller.rb +61 -0
- data/lib/vines/services/controller/labels_controller.rb +17 -0
- data/lib/vines/services/controller/members_controller.rb +44 -0
- data/lib/vines/services/controller/messages_controller.rb +66 -0
- data/lib/vines/services/controller/probes_controller.rb +45 -0
- data/lib/vines/services/controller/services_controller.rb +81 -0
- data/lib/vines/services/controller/subscriptions_controller.rb +39 -0
- data/lib/vines/services/controller/systems_controller.rb +45 -0
- data/lib/vines/services/controller/transfers_controller.rb +58 -0
- data/lib/vines/services/controller/uploads_controller.rb +62 -0
- data/lib/vines/services/controller/users_controller.rb +127 -0
- data/lib/vines/services/core_ext/blather.rb +46 -0
- data/lib/vines/services/core_ext/couchrest.rb +33 -0
- data/lib/vines/services/indexer.rb +195 -0
- data/lib/vines/services/priority_queue.rb +94 -0
- data/lib/vines/services/roster.rb +70 -0
- data/lib/vines/services/storage/couchdb/fragment.rb +23 -0
- data/lib/vines/services/storage/couchdb/service.rb +170 -0
- data/lib/vines/services/storage/couchdb/system.rb +141 -0
- data/lib/vines/services/storage/couchdb/upload.rb +66 -0
- data/lib/vines/services/storage/couchdb/user.rb +137 -0
- data/lib/vines/services/storage/couchdb/vcard.rb +13 -0
- data/lib/vines/services/storage/couchdb.rb +157 -0
- data/lib/vines/services/storage.rb +33 -0
- data/lib/vines/services/throttle.rb +26 -0
- data/lib/vines/services/version.rb +7 -0
- data/lib/vines/services/vql/compiler.rb +94 -0
- data/lib/vines/services/vql/vql.citrus +115 -0
- data/lib/vines/services/vql/vql.rb +186 -0
- data/lib/vines/services.rb +71 -0
- data/test/config_test.rb +242 -0
- data/test/priority_queue_test.rb +23 -0
- data/test/storage/couchdb_test.rb +30 -0
- data/test/vql/compiler_test.rb +96 -0
- data/test/vql/vql_test.rb +233 -0
- data/web/coffeescripts/api.coffee +51 -0
- data/web/coffeescripts/commands.coffee +18 -0
- data/web/coffeescripts/files.coffee +315 -0
- data/web/coffeescripts/init.coffee +21 -0
- data/web/coffeescripts/services.coffee +356 -0
- data/web/coffeescripts/setup.coffee +503 -0
- data/web/coffeescripts/systems.coffee +371 -0
- data/web/images/default-service.png +0 -0
- data/web/images/linux.png +0 -0
- data/web/images/mac.png +0 -0
- data/web/images/run.png +0 -0
- data/web/images/windows.png +0 -0
- data/web/index.html +17 -0
- data/web/stylesheets/common.css +52 -0
- data/web/stylesheets/files.css +218 -0
- data/web/stylesheets/services.css +181 -0
- data/web/stylesheets/setup.css +117 -0
- data/web/stylesheets/systems.css +142 -0
- metadata +230 -0
@@ -0,0 +1,371 @@
|
|
1
|
+
class SystemsPage
|
2
|
+
constructor: (@session) ->
|
3
|
+
@session.onRoster ( ) => this.roster()
|
4
|
+
@session.onCard (c) => this.card(c)
|
5
|
+
@session.onMessage (m) => this.message(m)
|
6
|
+
@session.onPresence (p) => this.presence(p)
|
7
|
+
@commands = new Commands
|
8
|
+
@chats = {}
|
9
|
+
@currentContact = null
|
10
|
+
|
11
|
+
datef: (millis) ->
|
12
|
+
d = new Date(millis)
|
13
|
+
meridian = if d.getHours() >= 12 then ' pm' else ' am'
|
14
|
+
hour = if d.getHours() > 12 then d.getHours() - 12 else d.getHours()
|
15
|
+
hour = 12 if hour == 0
|
16
|
+
minutes = d.getMinutes() + ''
|
17
|
+
minutes = '0' + minutes if minutes.length == 1
|
18
|
+
hour + ':' + minutes + meridian
|
19
|
+
|
20
|
+
card: (card) ->
|
21
|
+
this.eachContact card.jid, (node) =>
|
22
|
+
$('.vcard-img', node).attr 'src', @session.avatar card.jid
|
23
|
+
|
24
|
+
roster: ->
|
25
|
+
roster = $('#roster')
|
26
|
+
|
27
|
+
$('li', roster).each (ix, node) =>
|
28
|
+
jid = $(node).attr('data-jid')
|
29
|
+
$(node).remove() unless @session.roster[jid]
|
30
|
+
|
31
|
+
setName = (node, contact) ->
|
32
|
+
$('.text', node).text contact.name || contact.jid
|
33
|
+
node.attr 'data-name', contact.name || ''
|
34
|
+
node.attr 'data-groups', contact.groups || ''
|
35
|
+
|
36
|
+
for jid, contact of @session.roster
|
37
|
+
found = $("#roster li[data-jid='#{jid}']")
|
38
|
+
setName(found, contact)
|
39
|
+
if found.length == 0
|
40
|
+
if contact.groups[0]=="Vines"
|
41
|
+
img_src = "/lib/images/default-service.png"
|
42
|
+
else
|
43
|
+
img_src = "#{@session.avatar jid}"
|
44
|
+
node = $("""
|
45
|
+
<li data-jid="#{jid}" data-name="" data-group="" class="offline">
|
46
|
+
<span class="text"></span>
|
47
|
+
<span class="status-msg">Offline</span>
|
48
|
+
<span class="unread" style="display:none;"></span>
|
49
|
+
<img class="vcard-img" id="#{jid}-avatar" alt="#{jid}" src="#{img_src}"/>
|
50
|
+
</li>
|
51
|
+
""").appendTo roster
|
52
|
+
setName(node, contact)
|
53
|
+
node.click (event) => this.selectContact(event)
|
54
|
+
|
55
|
+
message: (message) ->
|
56
|
+
this.queueMessage message
|
57
|
+
me = message.from == @session.jid()
|
58
|
+
from = message.from.split('/')[0]
|
59
|
+
thread = message.thread
|
60
|
+
|
61
|
+
if me || from || thread == @currentContact
|
62
|
+
bottom = this.atBottom()
|
63
|
+
this.appendMessage message
|
64
|
+
this.scroll() if bottom
|
65
|
+
else
|
66
|
+
chat = this.chat message.from
|
67
|
+
chat.unread++
|
68
|
+
this.eachContact from, (node) ->
|
69
|
+
$('.unread', node).text(chat.unread).show()
|
70
|
+
|
71
|
+
eachContact: (jid, callback) ->
|
72
|
+
for node in $("#roster li[data-jid='#{jid}']").get()
|
73
|
+
callback $(node)
|
74
|
+
|
75
|
+
appendMessage: (message) ->
|
76
|
+
from = message.from.split('/')[0]
|
77
|
+
contact = @session.roster[from]
|
78
|
+
name = if contact then (contact.name || from) else from
|
79
|
+
name = 'Me' if message.from == @session.jid()
|
80
|
+
node = $("""
|
81
|
+
<li data-jid="#{from}" style="display:none;">
|
82
|
+
<p><pre></pre></p>
|
83
|
+
<img alt="#{from}" src="#{@session.avatar from}"/>
|
84
|
+
<footer>
|
85
|
+
<span class="author"></span>
|
86
|
+
<span class="time">#{this.datef message.received}</span>
|
87
|
+
</footer>
|
88
|
+
</li>
|
89
|
+
""").appendTo '#messages'
|
90
|
+
|
91
|
+
$('pre', node).text message.text
|
92
|
+
$('.author', node).text name
|
93
|
+
node.fadeIn 200
|
94
|
+
|
95
|
+
queueMessage: (message) ->
|
96
|
+
me = message.from == @session.jid()
|
97
|
+
full = message[if me then 'to' else 'from']
|
98
|
+
chat = this.chat full
|
99
|
+
chat.jid = full
|
100
|
+
chat.messages.push message
|
101
|
+
|
102
|
+
chat: (jid) ->
|
103
|
+
bare = jid.split('/')[0]
|
104
|
+
chat = @chats[bare]
|
105
|
+
unless chat
|
106
|
+
chat = jid: jid, messages: [], unread: 0
|
107
|
+
@chats[bare] = chat
|
108
|
+
chat
|
109
|
+
|
110
|
+
presence: (presence) ->
|
111
|
+
from = presence.from.split('/')[0]
|
112
|
+
return if from == @session.bareJid()
|
113
|
+
if !presence.type || presence.offline
|
114
|
+
contact = @session.roster[from]
|
115
|
+
this.eachContact from, (node) ->
|
116
|
+
$('.status-msg', node).text contact.status()
|
117
|
+
if contact.offline()
|
118
|
+
node.addClass 'offline'
|
119
|
+
else
|
120
|
+
node.removeClass 'offline'
|
121
|
+
|
122
|
+
if presence.offline
|
123
|
+
this.chat(from).jid = from
|
124
|
+
|
125
|
+
if presence.type == 'subscribe'
|
126
|
+
node = $("""
|
127
|
+
<li data-jid="#{presence.from}" style="display:none;">
|
128
|
+
<form class="inset">
|
129
|
+
<h2>Buddy Approval</h2>
|
130
|
+
<p>#{presence.from} wants to add you as a buddy.</p>
|
131
|
+
<fieldset class="buttons">
|
132
|
+
<input type="button" value="Decline"/>
|
133
|
+
<input type="submit" value="Accept"/>
|
134
|
+
</fieldset>
|
135
|
+
</form>
|
136
|
+
</li>
|
137
|
+
""").appendTo '#notifications'
|
138
|
+
node.fadeIn 200
|
139
|
+
$('form', node).submit => this.acceptContact node, presence.from
|
140
|
+
$('input[type="button"]', node).click => this.rejectContact node, presence.from
|
141
|
+
|
142
|
+
acceptContact: (node, jid) ->
|
143
|
+
node.fadeOut 200, -> node.remove()
|
144
|
+
@session.sendSubscribed jid
|
145
|
+
@session.sendSubscribe jid
|
146
|
+
false
|
147
|
+
|
148
|
+
rejectContact: (node, jid) ->
|
149
|
+
node.fadeOut 200, -> node.remove()
|
150
|
+
@session.sendUnsubscribed jid
|
151
|
+
|
152
|
+
selectContact: (event) ->
|
153
|
+
jid = $(event.currentTarget).attr 'data-jid'
|
154
|
+
contact = @session.roster[jid]
|
155
|
+
return if @currentContact == jid
|
156
|
+
@currentContact = jid
|
157
|
+
|
158
|
+
$('#roster li').removeClass 'selected'
|
159
|
+
$(event.currentTarget).addClass 'selected'
|
160
|
+
$('#chat-title').text('Chat with ' + (contact.name || contact.jid))
|
161
|
+
$('#messages').empty()
|
162
|
+
|
163
|
+
chat = @chats[jid]
|
164
|
+
messages = []
|
165
|
+
if chat
|
166
|
+
messages = chat.messages
|
167
|
+
chat.unread = 0
|
168
|
+
this.eachContact jid, (node) ->
|
169
|
+
$('.unread', node).text('').hide()
|
170
|
+
|
171
|
+
this.appendMessage msg for msg in messages
|
172
|
+
this.scroll()
|
173
|
+
|
174
|
+
$('#remove-contact-msg').html "Are you sure you want to remove " +
|
175
|
+
"<strong>#{@currentContact}</strong> from your buddy list?"
|
176
|
+
$('#remove-contact-form .buttons').fadeIn 200
|
177
|
+
|
178
|
+
$('#edit-contact-jid').text @currentContact
|
179
|
+
$('#edit-contact-name').val @session.roster[@currentContact].name
|
180
|
+
$('#edit-contact-form input').fadeIn 200
|
181
|
+
$('#edit-contact-form .buttons').fadeIn 200
|
182
|
+
|
183
|
+
scroll: ->
|
184
|
+
msgs = $ '#messages'
|
185
|
+
msgs.animate(scrollTop: msgs.prop('scrollHeight'), 400)
|
186
|
+
|
187
|
+
atBottom: ->
|
188
|
+
msgs = $('#messages')
|
189
|
+
bottom = msgs.prop('scrollHeight') - msgs.height()
|
190
|
+
msgs.scrollTop() == bottom
|
191
|
+
|
192
|
+
send: ->
|
193
|
+
return false unless @currentContact
|
194
|
+
input = $('#message')
|
195
|
+
text = input.val().trim()
|
196
|
+
if text
|
197
|
+
chat = @chats[@currentContact]
|
198
|
+
jid = if chat then chat.jid else @currentContact
|
199
|
+
this.message
|
200
|
+
from: @session.jid()
|
201
|
+
text: text
|
202
|
+
to: jid
|
203
|
+
received: new Date()
|
204
|
+
@session.sendMessage jid, text
|
205
|
+
@commands.push text
|
206
|
+
input.val ''
|
207
|
+
false
|
208
|
+
|
209
|
+
addContact: ->
|
210
|
+
this.toggleForm '#add-contact-form'
|
211
|
+
contact =
|
212
|
+
jid: $('#add-contact-jid').val()
|
213
|
+
name: $('#add-contact-name').val()
|
214
|
+
groups: ['Buddies']
|
215
|
+
@session.updateContact contact, true if contact.jid
|
216
|
+
false
|
217
|
+
|
218
|
+
removeContact: ->
|
219
|
+
this.toggleForm '#remove-contact-form'
|
220
|
+
@session.removeContact @currentContact
|
221
|
+
@currentContact = null
|
222
|
+
|
223
|
+
$('#chat-title').text 'Select a buddy to chat'
|
224
|
+
$('#messages').empty()
|
225
|
+
|
226
|
+
$('#remove-contact-msg').html "Select a buddy in the list above to remove."
|
227
|
+
$('#remove-contact-form .buttons').hide()
|
228
|
+
|
229
|
+
$('#edit-contact-jid').text "Select a buddy in the list above to update."
|
230
|
+
$('#edit-contact-name').val ''
|
231
|
+
$('#edit-contact-form input').hide()
|
232
|
+
$('#edit-contact-form .buttons').hide()
|
233
|
+
false
|
234
|
+
|
235
|
+
updateContact: ->
|
236
|
+
this.toggleForm '#edit-contact-form'
|
237
|
+
contact =
|
238
|
+
jid: @currentContact
|
239
|
+
name: $('#edit-contact-name').val()
|
240
|
+
groups: @session.roster[@currentContact].groups
|
241
|
+
@session.updateContact contact
|
242
|
+
false
|
243
|
+
|
244
|
+
toggleForm: (form, fn) ->
|
245
|
+
form = $(form)
|
246
|
+
$('form.overlay').each ->
|
247
|
+
$(this).hide() unless this.id == form.attr 'id'
|
248
|
+
if form.is ':hidden'
|
249
|
+
fn() if fn
|
250
|
+
form.fadeIn 100
|
251
|
+
else
|
252
|
+
form.fadeOut 100, ->
|
253
|
+
form[0].reset()
|
254
|
+
fn() if fn
|
255
|
+
|
256
|
+
draw: ->
|
257
|
+
unless @session.connected()
|
258
|
+
window.location.hash = ''
|
259
|
+
return
|
260
|
+
|
261
|
+
$('body').attr 'id', 'servers-page'
|
262
|
+
$('#container').hide().empty()
|
263
|
+
$("""
|
264
|
+
<div id="alpha" class="sidebar column y-fill">
|
265
|
+
<h2>Buddies <div id="search-roster-icon"></div></h2>
|
266
|
+
<div id="search-roster-form"></div>
|
267
|
+
<ul id="roster" class="selectable scroll y-fill"></ul>
|
268
|
+
<div id="alpha-controls" class="controls">
|
269
|
+
<div id="add-contact"></div>
|
270
|
+
<div id="remove-contact"></div>
|
271
|
+
<div id="edit-contact"></div>
|
272
|
+
</div>
|
273
|
+
<form id="add-contact-form" class="overlay" style="display:none;">
|
274
|
+
<h2>Add Buddy</h2>
|
275
|
+
<input id="add-contact-jid" type="email" maxlength="1024" placeholder="Account name"/>
|
276
|
+
<input id="add-contact-name" type="text" maxlength="1024" placeholder="Real name"/>
|
277
|
+
<fieldset class="buttons">
|
278
|
+
<input id="add-contact-cancel" type="button" value="Cancel"/>
|
279
|
+
<input id="add-contact-ok" type="submit" value="Add"/>
|
280
|
+
</fieldset>
|
281
|
+
</form>
|
282
|
+
<form id="remove-contact-form" class="overlay" style="display:none;">
|
283
|
+
<h2>Remove Buddy</h2>
|
284
|
+
<p id="remove-contact-msg">Select a buddy in the list above to remove.</p>
|
285
|
+
<fieldset class="buttons" style="display:none;">
|
286
|
+
<input id="remove-contact-cancel" type="button" value="Cancel"/>
|
287
|
+
<input id="remove-contact-ok" type="submit" value="Remove"/>
|
288
|
+
</fieldset>
|
289
|
+
</form>
|
290
|
+
<form id="edit-contact-form" class="overlay" style="display:none;">
|
291
|
+
<h2>Update Profile</h2>
|
292
|
+
<p id="edit-contact-jid">Select a buddy in the list above to update.</p>
|
293
|
+
<input id="edit-contact-name" type="text" maxlength="1024" placeholder="Real name" style="display:none;"/>
|
294
|
+
<fieldset class="buttons" style="display:none;">
|
295
|
+
<input id="edit-contact-cancel" type="button" value="Cancel"/>
|
296
|
+
<input id="edit-contact-ok" type="submit" value="Save"/>
|
297
|
+
</fieldset>
|
298
|
+
</form>
|
299
|
+
</div>
|
300
|
+
<div id="beta" class="primary column x-fill y-fill">
|
301
|
+
<h2 id="chat-title">Select a buddy or service to start communicating</h2>
|
302
|
+
<ul id="messages" class="scroll y-fill"></ul>
|
303
|
+
<form id="message-form">
|
304
|
+
<input id="message" name="message" type="text" maxlength="1024" placeholder="Type a message and press enter to send"/>
|
305
|
+
</form>
|
306
|
+
</div>
|
307
|
+
<div id="charlie" class="sidebar column y-fill">
|
308
|
+
<h2>Notifications</h2>
|
309
|
+
<ul id="notifications" class="scroll y-fill"></ul>
|
310
|
+
<div id="charlie-controls" class="controls">
|
311
|
+
<div id="clear-notices"></div>
|
312
|
+
</div>
|
313
|
+
</div>
|
314
|
+
""").appendTo '#container'
|
315
|
+
|
316
|
+
this.roster()
|
317
|
+
|
318
|
+
new Button '#clear-notices', ICONS.no
|
319
|
+
new Button '#add-contact', ICONS.plus
|
320
|
+
new Button '#remove-contact', ICONS.minus
|
321
|
+
new Button '#edit-contact', ICONS.user
|
322
|
+
|
323
|
+
$('#message').focus -> $('form.overlay').fadeOut()
|
324
|
+
$('#message').keyup (e) =>
|
325
|
+
switch e.keyCode # up, down keys trigger history
|
326
|
+
when 38 then $('#message').val @commands.prev()
|
327
|
+
when 40 then $('#message').val @commands.next()
|
328
|
+
|
329
|
+
$('#message-form').submit => this.send()
|
330
|
+
|
331
|
+
$('#clear-notices').click -> $('#notifications li').fadeOut 200
|
332
|
+
|
333
|
+
$('#add-contact').click => this.toggleForm '#add-contact-form'
|
334
|
+
$('#remove-contact').click => this.toggleForm '#remove-contact-form'
|
335
|
+
$('#edit-contact').click => this.toggleForm '#edit-contact-form', =>
|
336
|
+
if @currentContact
|
337
|
+
$('#edit-contact-jid').text @currentContact
|
338
|
+
$('#edit-contact-name').val @session.roster[@currentContact].name
|
339
|
+
|
340
|
+
$('#add-contact-cancel').click => this.toggleForm '#add-contact-form'
|
341
|
+
$('#remove-contact-cancel').click => this.toggleForm '#remove-contact-form'
|
342
|
+
$('#edit-contact-cancel').click => this.toggleForm '#edit-contact-form'
|
343
|
+
|
344
|
+
$('#add-contact-form').submit => this.addContact()
|
345
|
+
$('#remove-contact-form').submit => this.removeContact()
|
346
|
+
$('#edit-contact-form').submit => this.updateContact()
|
347
|
+
|
348
|
+
$('#container').show()
|
349
|
+
layout = this.resize()
|
350
|
+
|
351
|
+
fn = ->
|
352
|
+
layout.resize()
|
353
|
+
layout.resize() # not sure why two are needed
|
354
|
+
|
355
|
+
new Filter
|
356
|
+
list: '#roster'
|
357
|
+
icon: '#search-roster-icon'
|
358
|
+
form: '#search-roster-form'
|
359
|
+
attrs: ['data-jid', 'data-name']
|
360
|
+
open: fn
|
361
|
+
close: fn
|
362
|
+
|
363
|
+
resize: ->
|
364
|
+
a = $ '#alpha'
|
365
|
+
b = $ '#beta'
|
366
|
+
c = $ '#charlie'
|
367
|
+
msg = $ '#message'
|
368
|
+
form = $ '#message-form'
|
369
|
+
new Layout ->
|
370
|
+
c.css 'left', a.width() + b.width()
|
371
|
+
msg.width form.width() - 32
|
Binary file
|
Binary file
|
data/web/images/mac.png
ADDED
Binary file
|
data/web/images/run.png
ADDED
Binary file
|
Binary file
|
data/web/index.html
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
5
|
+
<meta charset="utf-8">
|
6
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
7
|
+
<title>Vines</title>
|
8
|
+
<link rel="shortcut icon" type="image/png" href="/favicon.png">
|
9
|
+
<script type="text/javascript" src="/lib/javascripts/base.js"></script>
|
10
|
+
<script type="text/javascript" src="javascripts/app.js"></script>
|
11
|
+
<link rel="stylesheet" href="/lib/stylesheets/base.css">
|
12
|
+
<link rel="stylesheet" href="/lib/stylesheets/login.css">
|
13
|
+
<link rel="stylesheet" href="stylesheets/app.css">
|
14
|
+
</head>
|
15
|
+
<body>
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#editor-buttons {
|
2
|
+
background: #f8f8f8;
|
3
|
+
border-top: 1px solid #dfdfdf;
|
4
|
+
height: 50px;
|
5
|
+
position: absolute;
|
6
|
+
bottom: 0;
|
7
|
+
width: 100%;
|
8
|
+
}
|
9
|
+
#editor-buttons {
|
10
|
+
text-align: right;
|
11
|
+
}
|
12
|
+
#editor-buttons #save {
|
13
|
+
position: relative;
|
14
|
+
right: 10px;
|
15
|
+
top: 10px;
|
16
|
+
}
|
17
|
+
form.sections h2 {
|
18
|
+
background: none;
|
19
|
+
border: none;
|
20
|
+
padding-left: 0;
|
21
|
+
}
|
22
|
+
form.sections label {
|
23
|
+
display: block;
|
24
|
+
font-weight: bold;
|
25
|
+
font-size: 9pt;
|
26
|
+
color: rgba(0,0,0,0.8);
|
27
|
+
margin: 10px 0 -2px 0;
|
28
|
+
}
|
29
|
+
form.sections input[type="text"],
|
30
|
+
form.sections input[type="email"],
|
31
|
+
form.sections input[type="password"],
|
32
|
+
form.sections textarea {
|
33
|
+
width: 90%;
|
34
|
+
}
|
35
|
+
form.sections section {
|
36
|
+
border-bottom: 1px solid #ddd;
|
37
|
+
margin: 0 20px;
|
38
|
+
}
|
39
|
+
form.sections section fieldset {
|
40
|
+
padding-left: 30%;
|
41
|
+
margin-top: -33px;
|
42
|
+
margin-bottom: 10px;
|
43
|
+
}
|
44
|
+
form.sections section:last-child {
|
45
|
+
border-bottom: none;
|
46
|
+
margin-bottom: 20px;
|
47
|
+
}
|
48
|
+
form.sections .error {
|
49
|
+
color: #dd2828;
|
50
|
+
font-size: 8pt;
|
51
|
+
width: 89%;
|
52
|
+
}
|
@@ -0,0 +1,218 @@
|
|
1
|
+
#files-page #container {
|
2
|
+
height: 100%;
|
3
|
+
}
|
4
|
+
#files-page #files-title {
|
5
|
+
background: #f8f8f8;
|
6
|
+
}
|
7
|
+
#files-page #files {
|
8
|
+
background: #fff;
|
9
|
+
height: 100%;
|
10
|
+
list-style: none;
|
11
|
+
width: 100%;
|
12
|
+
}
|
13
|
+
#files-page #files li {
|
14
|
+
border-bottom: 1px solid #f0f0f0;
|
15
|
+
padding: 10px;
|
16
|
+
position: relative;
|
17
|
+
}
|
18
|
+
#files-page #files li .file-icon {
|
19
|
+
float: left;
|
20
|
+
}
|
21
|
+
#files-page #files li .file-icon > svg {
|
22
|
+
height: 30px;
|
23
|
+
width: 30px;
|
24
|
+
}
|
25
|
+
#files-page #files li .file-icon .size {
|
26
|
+
color: rgba(0, 0, 0, 0.7);
|
27
|
+
display: block;
|
28
|
+
font-size: 9pt;
|
29
|
+
line-height: 1;
|
30
|
+
}
|
31
|
+
#files-page #files li h2 {
|
32
|
+
border: none;
|
33
|
+
line-height: 1;
|
34
|
+
padding: 0 0 0 50px;
|
35
|
+
}
|
36
|
+
#files-page #files li:hover {
|
37
|
+
background: #fdfdfd;
|
38
|
+
}
|
39
|
+
#files-page #files li .file-form {
|
40
|
+
opacity: 0;
|
41
|
+
position: absolute;
|
42
|
+
right: 10px;
|
43
|
+
top: 22px;
|
44
|
+
-moz-transition: opacity 0.3s;
|
45
|
+
-o-transition: opacity 0.3s;
|
46
|
+
-webkit-transition: opacity 0.3s;
|
47
|
+
transition: opacity 0.3s;
|
48
|
+
}
|
49
|
+
#files-page #files li:hover .file-form {
|
50
|
+
opacity: 1.0;
|
51
|
+
}
|
52
|
+
#files-page #files li:hover footer {
|
53
|
+
color: rgba(0, 0, 0, 0.7);
|
54
|
+
}
|
55
|
+
#files-page #files li footer {
|
56
|
+
color: rgba(0, 0, 0, 0.3);
|
57
|
+
font-size: 9pt;
|
58
|
+
padding-left: 50px;
|
59
|
+
-moz-transition: color 0.3s;
|
60
|
+
-o-transition: color 0.3s;
|
61
|
+
-webkit-transition: color 0.3s;
|
62
|
+
transition: color 0.3s;
|
63
|
+
}
|
64
|
+
#files-page #files li .time {
|
65
|
+
display: block;
|
66
|
+
}
|
67
|
+
#files-page #files li .labels {
|
68
|
+
line-height: 1;
|
69
|
+
min-height: 10px;
|
70
|
+
width: 80%;
|
71
|
+
}
|
72
|
+
#files-page #files li .labels li {
|
73
|
+
border: none;
|
74
|
+
display: inline-block;
|
75
|
+
line-height: 1;
|
76
|
+
margin-right: 10px;
|
77
|
+
margin-bottom: 7px;
|
78
|
+
padding: 0 12px 0 0;
|
79
|
+
position: relative;
|
80
|
+
text-transform: capitalize;
|
81
|
+
}
|
82
|
+
#files-page #files li .labels li .remove {
|
83
|
+
cursor: pointer;
|
84
|
+
position: absolute;
|
85
|
+
right: 0;
|
86
|
+
top: -2px;
|
87
|
+
width: 14px;
|
88
|
+
}
|
89
|
+
#files-page #files li .labels li .remove svg {
|
90
|
+
height: 12px;
|
91
|
+
width: 12px;
|
92
|
+
}
|
93
|
+
#files-page #files .add-label-button {
|
94
|
+
cursor: pointer;
|
95
|
+
display: inline-block;
|
96
|
+
margin-right: 3px;
|
97
|
+
}
|
98
|
+
#files-page #files .add-label-button svg {
|
99
|
+
height: 14px;
|
100
|
+
width: 14px;
|
101
|
+
}
|
102
|
+
#files-page #files form.add-label input[type="text"] {
|
103
|
+
display: inline-block;
|
104
|
+
font-size: 8pt;
|
105
|
+
padding: 2px;
|
106
|
+
position: relative;
|
107
|
+
top: -4px;
|
108
|
+
width: 100px;
|
109
|
+
}
|
110
|
+
#files-page #file-chooser {
|
111
|
+
height: 30px;
|
112
|
+
opacity: 0;
|
113
|
+
position: absolute;
|
114
|
+
top: 10px;
|
115
|
+
left: 10px;
|
116
|
+
}
|
117
|
+
#files-page #open-file-chooser {
|
118
|
+
height: 30px;
|
119
|
+
margin: 0;
|
120
|
+
position: absolute;
|
121
|
+
top: 10px;
|
122
|
+
left: 10px;
|
123
|
+
width: 240px;
|
124
|
+
}
|
125
|
+
#files-page #upload-dnd {
|
126
|
+
color: #ababab;
|
127
|
+
font-weight: bold;
|
128
|
+
font-size: 14px;
|
129
|
+
position: absolute;
|
130
|
+
top: 27px;
|
131
|
+
text-align: center;
|
132
|
+
text-shadow: 0 1px 1px #fff;
|
133
|
+
width: 260px;
|
134
|
+
}
|
135
|
+
#files-page #uploads .progress {
|
136
|
+
background: #fff;
|
137
|
+
border: 1px solid #448ccd;
|
138
|
+
border-top: 1px solid #5da8db;
|
139
|
+
border-radius: 3px;
|
140
|
+
-webkit-box-shadow: 0 1px 1px #fff, inset 0 1px 1px rgba(255, 255, 255, 0.5);
|
141
|
+
box-shadow: 0 1px 1px #fff, inset 0 1px 1px rgba(255, 255, 255, 0.5);
|
142
|
+
color: #0d4078;
|
143
|
+
font-size: 11px;
|
144
|
+
font-weight: bold;
|
145
|
+
height: 15px;
|
146
|
+
line-height: 15px;
|
147
|
+
margin: 0 10px 10px 10px;
|
148
|
+
position: relative;
|
149
|
+
text-align: center;
|
150
|
+
text-shadow: 0 1px 1px #a2d8f8;
|
151
|
+
}
|
152
|
+
#files-page #uploads .progress .text {
|
153
|
+
position: absolute;
|
154
|
+
left: 0;
|
155
|
+
width: 100%;
|
156
|
+
}
|
157
|
+
#files-page #uploads .progress .meter {
|
158
|
+
background: #8dd2f7;
|
159
|
+
background: -moz-linear-gradient(#8dd2f7, #58b8f4);
|
160
|
+
background: -o-linear-gradient(#8dd2f7, #58b8f4);
|
161
|
+
background: -webkit-gradient(linear, left top, left bottom, from(#8dd2f7), to(#58b8f4));
|
162
|
+
height: 15px;
|
163
|
+
position: absolute;
|
164
|
+
top: 0;
|
165
|
+
}
|
166
|
+
#files-page #uploads .progress .cancel {
|
167
|
+
height: 100%;
|
168
|
+
width: 16px;
|
169
|
+
position: absolute;
|
170
|
+
right: 0;
|
171
|
+
}
|
172
|
+
#files-page #labels,
|
173
|
+
#files-page #uploads {
|
174
|
+
height: 100%;
|
175
|
+
list-style: none;
|
176
|
+
text-shadow: 0 1px 1px #fff;
|
177
|
+
width: 260px;
|
178
|
+
}
|
179
|
+
#files-page #labels li .text {
|
180
|
+
text-transform: capitalize;
|
181
|
+
}
|
182
|
+
#files-page #labels li,
|
183
|
+
#files-page #uploads li {
|
184
|
+
cursor: pointer;
|
185
|
+
border-bottom: 1px solid #ddd;
|
186
|
+
font-weight: bold;
|
187
|
+
min-height: 42px;
|
188
|
+
padding: 0 10px;
|
189
|
+
position: relative;
|
190
|
+
-moz-transition: background 0.3s;
|
191
|
+
-o-transition: background 0.3s;
|
192
|
+
-webkit-transition: background 0.3s;
|
193
|
+
transition: background 0.3s;
|
194
|
+
}
|
195
|
+
#files-page #uploads li {
|
196
|
+
font-weight: normal;
|
197
|
+
padding: 10px 0 0 0;
|
198
|
+
background: #f8f8f8;
|
199
|
+
}
|
200
|
+
#files-page #labels li:hover:not(.selected),
|
201
|
+
#files-page #uploads li:hover {
|
202
|
+
background: rgba(255, 255, 255, 1.0);
|
203
|
+
}
|
204
|
+
#files-page #labels li.selected .count {
|
205
|
+
color: rgba(255, 255, 255, 0.85);
|
206
|
+
}
|
207
|
+
#files-page #labels .count {
|
208
|
+
display: block;
|
209
|
+
font-size: 11px;
|
210
|
+
font-weight: normal;
|
211
|
+
line-height: 11px;
|
212
|
+
}
|
213
|
+
#files-page #charlie-controls {
|
214
|
+
text-align: right;
|
215
|
+
}
|
216
|
+
#files-page #search-files-form {
|
217
|
+
background: #f8f8f8;
|
218
|
+
}
|