Moved to flask, added virtual databases and login
This commit is contained in:
parent
107d35bea0
commit
ed49d343f8
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
bin/*
|
||||||
|
include/*
|
||||||
|
lib/*
|
||||||
|
lib64
|
||||||
|
__pycache__/*
|
||||||
|
share/*
|
||||||
|
pyvenv.cfg
|
||||||
|
key.txt
|
||||||
|
db.info
|
||||||
|
config.ini
|
||||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
461
binbin.py
Normal file
461
binbin.py
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
import sys, os, time, hashlib, uuid, threading, atexit, flask, \
|
||||||
|
configparser as cp
|
||||||
|
from flask import Flask, render_template, url_for, request, session, \
|
||||||
|
send_from_directory, send_file, redirect
|
||||||
|
from flask_pymongo import PyMongo, ObjectId
|
||||||
|
|
||||||
|
FILTERS = {
|
||||||
|
'name': 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +
|
||||||
|
'0123456789_',
|
||||||
|
'path': ['../', './']
|
||||||
|
}
|
||||||
|
|
||||||
|
def apply_config():
|
||||||
|
config = cp.ConfigParser()
|
||||||
|
config.read('config.ini')
|
||||||
|
for k,v in config['Settings'].items():
|
||||||
|
k = k.upper()
|
||||||
|
if k == 'KEY_FILE':
|
||||||
|
app.secret_key = open(v, 'rb').read()
|
||||||
|
elif k == 'DEFAULT_VIRTUAL_SIZE':
|
||||||
|
app.config[k] = int(v)
|
||||||
|
else:
|
||||||
|
app.config[k] = v
|
||||||
|
|
||||||
|
|
||||||
|
os.chdir(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
apply_config()
|
||||||
|
mongo = PyMongo(app)
|
||||||
|
USERS, DRIVES, LINKS = mongo.db['users'], mongo.db['drives'], \
|
||||||
|
mongo.db['links']
|
||||||
|
|
||||||
|
CHECK_PERIOD = 60
|
||||||
|
expire_thread = threading.Thread()
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def index():
|
||||||
|
if 'username' in session:
|
||||||
|
return render_template('pre_main.html')
|
||||||
|
else:
|
||||||
|
return render_template('index.html')
|
||||||
|
|
||||||
|
@app.route('/main/<method>')
|
||||||
|
def main(method):
|
||||||
|
return render_template(method+'.html')
|
||||||
|
|
||||||
|
@app.route('/login', methods=['POST'])
|
||||||
|
def login():
|
||||||
|
error = None
|
||||||
|
u, p = request.form['username'], request.form['password']
|
||||||
|
success = validate_login(u, p)
|
||||||
|
if success:
|
||||||
|
session['username'] = u
|
||||||
|
return flask.jsonify(True)
|
||||||
|
else:
|
||||||
|
return flask.jsonify(False)
|
||||||
|
|
||||||
|
@app.route('/logout')
|
||||||
|
def logout():
|
||||||
|
session.pop('username', None)
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
@app.route('/mydrives')
|
||||||
|
def mydrives():
|
||||||
|
if 'username' not in session:
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
user_id = get_user(session)['_id']
|
||||||
|
owned = DRIVES.find({'owner': user_id})
|
||||||
|
shared = DRIVES.find({'shared_read': {'$in': [user_id]}})
|
||||||
|
|
||||||
|
info = {'owned': [], 'shared': []}
|
||||||
|
|
||||||
|
for drive in owned:
|
||||||
|
drive_info = {
|
||||||
|
'_id': str(drive['_id']),
|
||||||
|
'name': drive['name'],
|
||||||
|
'size': drive['size'],
|
||||||
|
'public_read': drive['public_read'],
|
||||||
|
'public_write': drive['public_write'],
|
||||||
|
'shared_read': [str(i) for i in drive['shared_read']],
|
||||||
|
'shared_write': [str(i) for i in drive['shared_write']]
|
||||||
|
}
|
||||||
|
info['owned'].append(drive_info)
|
||||||
|
|
||||||
|
for drive in shared:
|
||||||
|
drive_info = {
|
||||||
|
'_id': str(drive['_id']),
|
||||||
|
'name': drive['name'],
|
||||||
|
'size': drive['size']
|
||||||
|
}
|
||||||
|
info['shared'].append(drive_info)
|
||||||
|
|
||||||
|
return flask.jsonify(info)
|
||||||
|
|
||||||
|
@app.route('/files', methods=['POST'])
|
||||||
|
def files():
|
||||||
|
check = verify_data('files', request.form, session)
|
||||||
|
if not check[0]: return check[1]
|
||||||
|
form = check[1]
|
||||||
|
|
||||||
|
if form['is_fol']: # If request is a folder.
|
||||||
|
info = dir_info(form['path'], form['drive']['type'], \
|
||||||
|
form['drive']['_id'])
|
||||||
|
return flask.jsonify(info)
|
||||||
|
else: # If request is a file.
|
||||||
|
if form['drive']['type'] == 'real':
|
||||||
|
link = LINKS.insert_one({
|
||||||
|
'path': form['path'],
|
||||||
|
'name': form['path'].split("/")[-1],
|
||||||
|
'shared': [get_user(session)['_id']],
|
||||||
|
'expiry': -1
|
||||||
|
}).inserted_id
|
||||||
|
elif form['drive']['type'] == 'virtual':
|
||||||
|
r_path = form['drive']['path'] + '/' + form['real_file']
|
||||||
|
link = LINKS.insert_one({
|
||||||
|
'path': r_path,
|
||||||
|
'name': form['path'].split("/")[-1],
|
||||||
|
'shared': [get_user(session)['_id']],
|
||||||
|
'expiry': -1
|
||||||
|
}).inserted_id
|
||||||
|
else:
|
||||||
|
raise Exception("Invalid method for file link creation.")
|
||||||
|
### QUEUE DELETION
|
||||||
|
return str(link)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/d/<_id>')
|
||||||
|
def download(_id):
|
||||||
|
if 'username' not in session:
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
try:
|
||||||
|
link = LINKS.find_one({'_id': ObjectId(_id)})
|
||||||
|
except:
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
if link == None: return redirect(url_for('index'))
|
||||||
|
if get_user(session)['_id'] not in link['shared']:
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
else:
|
||||||
|
if link['expiry'] == -1:
|
||||||
|
LINKS.delete_one({'_id': ObjectId(_id)})
|
||||||
|
return send_file(link['path'], as_attachment=True,
|
||||||
|
attachment_filename=link['name'])
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/users/<method>', methods=['POST'])
|
||||||
|
def users(method):
|
||||||
|
if 'username' not in session:
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
user = USERS.find_one({'username': session['username']})
|
||||||
|
|
||||||
|
if method == 'create':
|
||||||
|
check = verify_data('users.create', request.form, session)
|
||||||
|
if not check[0]: return check[1]
|
||||||
|
form = check[1]
|
||||||
|
|
||||||
|
salt = uuid.uuid4().hex
|
||||||
|
to_hash = (form['password'] + salt).encode('utf-8')
|
||||||
|
user = USERS.insert_one({
|
||||||
|
'username': form['username'],
|
||||||
|
'password': hashlib.sha512(to_hash).digest(),
|
||||||
|
'salt': salt,
|
||||||
|
'perm_level': 1
|
||||||
|
})
|
||||||
|
|
||||||
|
create_drive('virtual', user.inserted_id)
|
||||||
|
|
||||||
|
elif method == 'delete':
|
||||||
|
check = verify_data('users.delete', request.form, session)
|
||||||
|
if not check[0]: return check[1]
|
||||||
|
form = check[1]
|
||||||
|
USERS.delete_one({'username': form['username']})
|
||||||
|
|
||||||
|
elif method == 'modify':
|
||||||
|
pass
|
||||||
|
return 'Operation completed'
|
||||||
|
|
||||||
|
@app.route('/drive/<drive_id>/<path:path>')
|
||||||
|
def drive_path():
|
||||||
|
pass
|
||||||
|
|
||||||
|
@app.errorhandler(404)
|
||||||
|
def page_not_found(e):
|
||||||
|
return render_template('404.html'), 404
|
||||||
|
|
||||||
|
|
||||||
|
# Temporary for development:
|
||||||
|
@app.route('/css/<path:path>')
|
||||||
|
def css(path):
|
||||||
|
return send_from_directory('css', path)
|
||||||
|
|
||||||
|
@app.route('/js/<path:path>')
|
||||||
|
def js(path):
|
||||||
|
return send_from_directory('js', path)
|
||||||
|
|
||||||
|
@app.route('/assets/<path:path>')
|
||||||
|
def assets(path):
|
||||||
|
return send_from_directory('assets', path)
|
||||||
|
|
||||||
|
# End temporary
|
||||||
|
|
||||||
|
def get_user(sess):
|
||||||
|
return USERS.find_one({'username': session['username']})
|
||||||
|
|
||||||
|
|
||||||
|
def validate_login(u, p):
|
||||||
|
user = USERS.find_one({'username': u})
|
||||||
|
if user == None:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
to_hash = (p + user['salt']).encode('utf-8')
|
||||||
|
return hashlib.sha512(to_hash).digest() == user['password']
|
||||||
|
|
||||||
|
|
||||||
|
def sizeof_fmt(num, suffix='B'):
|
||||||
|
for unit in ['','K','M','G','T','P','E','Z']:
|
||||||
|
if abs(num) < 1024.0:
|
||||||
|
return '%3.1f%s%s' % (num, unit, suffix)
|
||||||
|
num /= 1024.0
|
||||||
|
return '%.1f%s%s' % (num, 'Y', suffix)
|
||||||
|
|
||||||
|
|
||||||
|
def dir_info(path, t, drive_id):
|
||||||
|
def info_dict(item, stats, is_fol):
|
||||||
|
if is_fol:
|
||||||
|
my_item = ({
|
||||||
|
'folder': True,
|
||||||
|
'name': item
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
my_item = ({
|
||||||
|
'folder': False,
|
||||||
|
'name': item,
|
||||||
|
'date': time.strftime('%Y-%m-%d %H:%M:%S UTC', \
|
||||||
|
time.gmtime(stats[8])),
|
||||||
|
'size': sizeof_fmt(stats[6]),
|
||||||
|
'real_size': stats[6]
|
||||||
|
})
|
||||||
|
return my_item
|
||||||
|
full_items = []
|
||||||
|
|
||||||
|
if t == 'real':
|
||||||
|
items = os.listdir(path)
|
||||||
|
for item in items:
|
||||||
|
stats = list(os.stat(path + '/' + item))
|
||||||
|
is_fol = os.path.isdir(path + '/' + item)
|
||||||
|
full_items.append(info_dict(item, stats, is_fol))
|
||||||
|
|
||||||
|
elif t == 'virtual':
|
||||||
|
drives = DRIVES.find_one({'_id': drive_id})
|
||||||
|
tree = drives['tree']
|
||||||
|
path = path.replace('.',':').split("/")[1:]
|
||||||
|
if path != []:
|
||||||
|
for sub in path: tree = tree[sub]
|
||||||
|
|
||||||
|
for k,v in tree.items():
|
||||||
|
is_fol = type(v).__name__ != 'str'
|
||||||
|
if is_fol:
|
||||||
|
stats = None
|
||||||
|
else:
|
||||||
|
stats = list(os.stat(drives['path'] + '/' + v))
|
||||||
|
full_items.append(info_dict(k.replace(':','.'), \
|
||||||
|
stats, is_fol))
|
||||||
|
|
||||||
|
return full_items
|
||||||
|
|
||||||
|
|
||||||
|
def exists(data, need):
|
||||||
|
try:
|
||||||
|
[i in data for i in need].index(False)
|
||||||
|
return False
|
||||||
|
except ValueError:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def sanitize(d):
|
||||||
|
if 'username' in d:
|
||||||
|
s = ''
|
||||||
|
for c in d['username']: s += c if c in FILTERS['name'] else ''
|
||||||
|
d['username'] = s
|
||||||
|
|
||||||
|
if 'path' in d:
|
||||||
|
for s in FILTERS['path']:
|
||||||
|
if s in d['path']:
|
||||||
|
d['path'] = ''
|
||||||
|
|
||||||
|
|
||||||
|
def sess_is_user(sess, name):
|
||||||
|
return sess['username'] == name
|
||||||
|
|
||||||
|
|
||||||
|
def sess_is_admin(sess):
|
||||||
|
return get_user(sess)['perm_level'] == 100
|
||||||
|
|
||||||
|
|
||||||
|
def copy_dict(form):
|
||||||
|
new_form = {}
|
||||||
|
for k,v in form.items(): new_form[k] = v
|
||||||
|
return new_form
|
||||||
|
|
||||||
|
|
||||||
|
def verify_data(method, form, sess):
|
||||||
|
'''
|
||||||
|
Verifies permissions and format and sanitizes user input.
|
||||||
|
For each method, 1) Check for malformed data. 3) Check permissions
|
||||||
|
for operation based on session. 3) Sanitize data. 4) Check
|
||||||
|
operation specific requirements.
|
||||||
|
'''
|
||||||
|
|
||||||
|
err_msgs = {
|
||||||
|
'data': 'malformed data',
|
||||||
|
'permission': 'insufficient permissions',
|
||||||
|
'userexists': 'username already in use',
|
||||||
|
'driveperm': 'the drive is not shared with you',
|
||||||
|
'pathinvalid': 'not a valid path'
|
||||||
|
}
|
||||||
|
|
||||||
|
errors = []
|
||||||
|
data = copy_dict(form)
|
||||||
|
if method == 'users.create':
|
||||||
|
has_items = exists(data, ['username', 'password'])
|
||||||
|
if not has_items: errors.append('data')
|
||||||
|
if not sess_is_admin(sess): errors.append('permission')
|
||||||
|
|
||||||
|
sanitize(data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if USERS.find_one({'username': data['username']}) != None:
|
||||||
|
errors.append('userexists')
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
elif method == 'users.delete':
|
||||||
|
has_items = exists(data, ['username'])
|
||||||
|
if not has_items: errors.append('data')
|
||||||
|
if not sess_is_admin(sess) and \
|
||||||
|
not sess_is_user(sess, data['username']):
|
||||||
|
return errors.append('permission')
|
||||||
|
|
||||||
|
sanitize(data)
|
||||||
|
|
||||||
|
elif method == 'users.modify':
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif method == 'files':
|
||||||
|
has_items = exists(data, ['drive_id', 'path'])
|
||||||
|
if not has_items: errors.append('data')
|
||||||
|
|
||||||
|
drive = DRIVES.find_one({'_id': ObjectId(data['drive_id'])})
|
||||||
|
if drive == None: errors.append('driveinvalid')
|
||||||
|
|
||||||
|
if not drive['public_read']:
|
||||||
|
user_id = get_user(sess)['_id']
|
||||||
|
if user_id != drive['owner'] and \
|
||||||
|
user_id not in drive['shared_read']:
|
||||||
|
errors.append('driveperm')
|
||||||
|
|
||||||
|
sanitize(data)
|
||||||
|
|
||||||
|
if drive['type'] == 'real':
|
||||||
|
if not os.path.exists(drive['path'] + data['path']):
|
||||||
|
errors.append('pathinvalid')
|
||||||
|
data['is_fol'] = os.path.isdir(drive['path'] + \
|
||||||
|
data['path'])
|
||||||
|
|
||||||
|
# For real drives, the path is kept as the full real path.
|
||||||
|
data['path'] = drive['path']+data['path']
|
||||||
|
elif drive['type'] == 'virtual':
|
||||||
|
tree = drive['tree']
|
||||||
|
path = data['path'].replace('.',':').split('/')[1:]
|
||||||
|
if path != []:
|
||||||
|
folder, f = path[:-1], path[-1]
|
||||||
|
try:
|
||||||
|
for sub in folder: tree = tree[sub]
|
||||||
|
data['is_fol'] = type(tree[f]).__name__ != 'str'
|
||||||
|
data['real_file'] = tree[f]
|
||||||
|
except KeyError:
|
||||||
|
errors.append('pathinvalid')
|
||||||
|
else:
|
||||||
|
data['is_fol'] = True
|
||||||
|
|
||||||
|
# For virtual drives, the path is just the user request.
|
||||||
|
|
||||||
|
data['drive'] = drive
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception('Invalid data verification method.')
|
||||||
|
|
||||||
|
if len(errors) == 0: return [True, data]
|
||||||
|
|
||||||
|
msg = 'Error: '
|
||||||
|
for i,e in enumerate(errors):
|
||||||
|
if len(errors) == 1:
|
||||||
|
msg += err_msgs[e][0].upper() + err_msgs[e][1:]
|
||||||
|
elif i == 0:
|
||||||
|
msg += err_msgs[e][0].upper() + err_msgs[e][1:] + ', '
|
||||||
|
elif i == len(errors)-1:
|
||||||
|
msg += 'and ' + err_msgs[e]
|
||||||
|
else:
|
||||||
|
msg += err_msgs[e] + ', '
|
||||||
|
msg += '.'
|
||||||
|
|
||||||
|
if len(errors) <= 2: msg = msg.replace(',', '')
|
||||||
|
|
||||||
|
return [False, msg]
|
||||||
|
|
||||||
|
|
||||||
|
def create_drive(method, owner, form=None):
|
||||||
|
if method == 'real':
|
||||||
|
DRIVES.insert_one({
|
||||||
|
'name': form['name'],
|
||||||
|
'path': form['path'],
|
||||||
|
'type': 'real',
|
||||||
|
'owner': owner,
|
||||||
|
'public_read': False,
|
||||||
|
'public_write': False,
|
||||||
|
'shared_read': [],
|
||||||
|
'shared_write': []
|
||||||
|
})
|
||||||
|
elif method == 'virtual':
|
||||||
|
vir_path = app.config['VIRTUAL_DB_PATH'] + "/" + str(owner)
|
||||||
|
name = str(uuid.uuid4())+str(uuid.uuid4())
|
||||||
|
DRIVES.insert_one({
|
||||||
|
'name': 'My Drive',
|
||||||
|
'path': vir_path,
|
||||||
|
'tree': {
|
||||||
|
'Welcome:txt': name
|
||||||
|
},
|
||||||
|
'type': 'virtual',
|
||||||
|
'size': app.config['DEFAULT_VIRTUAL_SIZE'],
|
||||||
|
'owner': owner,
|
||||||
|
'public_read': False,
|
||||||
|
'public_write': False,
|
||||||
|
'shared_read': [],
|
||||||
|
'shared_write': []
|
||||||
|
})
|
||||||
|
|
||||||
|
os.mkdir(vir_path)
|
||||||
|
file = open(vir_path+'/'+name, 'w')
|
||||||
|
file.write(app.config['WELCOME_MSG'])
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception('Invalid drive creation method.')
|
||||||
|
|
||||||
|
return 'Operation completed.'
|
||||||
|
|
||||||
|
|
||||||
|
def manage_expiry():
|
||||||
|
links = LINKS.find()
|
||||||
|
#print(links)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True)
|
||||||
1
binbin.wsgi
Normal file
1
binbin.wsgi
Normal file
@ -0,0 +1 @@
|
|||||||
|
from binbin import app as application
|
||||||
@ -1,4 +1,3 @@
|
|||||||
@import url(https://fonts.googleapis.com/css?family=Abel);
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
@ -41,15 +40,12 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
display: grid;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: white;
|
color: white;
|
||||||
font-family: 'Open Sans Condensed', sans-serif;
|
font-family: 'Roboto Slab', sans-serif;
|
||||||
grid-template-columns: 15% auto;
|
|
||||||
grid-template-rows: 8% auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, p {
|
h1, h2, h3, h4, h5, p {
|
||||||
@ -61,11 +57,6 @@ a {
|
|||||||
color: #2EA8FF;
|
color: #2EA8FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header1 h1 {
|
|
||||||
margin: auto;
|
|
||||||
font-size: 5vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.transition {
|
.transition {
|
||||||
-webkit-transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
-webkit-transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
||||||
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
||||||
@ -75,56 +66,56 @@ a {
|
|||||||
|
|
||||||
#header1 {
|
#header1 {
|
||||||
display: grid;
|
display: grid;
|
||||||
background-color: #292828;
|
background-color: #1b1a1a;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
grid-column: 1;
|
|
||||||
grid-row: 1;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
height: 10vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header1 img {
|
#header1 h1 {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
height: 80%;
|
font-size: 3em;
|
||||||
|
font-family: 'Roboto Slab', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header2 {
|
#header2 {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(8, 1fr);
|
grid-template-rows: 1fr 1fr 1fr;
|
||||||
background-color: #27262b;
|
background-color: #27262b;
|
||||||
grid-column: 2;
|
height: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#topNav {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(8, 1fr);
|
||||||
grid-row: 1;
|
grid-row: 1;
|
||||||
}
|
background-color: rgba(255,255,255,0.01);
|
||||||
|
|
||||||
#header2 div {
|
|
||||||
margin: auto;
|
|
||||||
font-size: 150%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header2 p {
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 5%;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header2 p:hover {
|
#logout {
|
||||||
|
margin: auto;
|
||||||
|
grid-column: 8;
|
||||||
|
font-size: 1.15em;
|
||||||
|
padding: .5em 0 .5em 0;
|
||||||
|
font-weight: 300;
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logout:hover {
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#header2 i {
|
|
||||||
margin-left: 2%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#spectrum {
|
|
||||||
grid-column: 5;
|
|
||||||
grid-row: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: #27262b;
|
background-color: #27262b;
|
||||||
grid-column: 1;
|
height: 100%;
|
||||||
grid-row: 2;
|
display: inline-block;
|
||||||
|
width: 30vh;
|
||||||
|
font-family: 'Saira Condensed', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar span {
|
#sidebar span {
|
||||||
@ -145,7 +136,17 @@ a {
|
|||||||
height: 6vh;
|
height: 6vh;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
grid-template-columns: 1fr 3fr 7fr;
|
grid-template-columns: 1fr 5fr 20fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.naviHead {
|
||||||
|
background-color: rgba(0,0,0,0.4);
|
||||||
|
padding: 3%;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.naviHead:first-child {
|
||||||
|
margin-top: 6vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.naviInner {
|
.naviInner {
|
||||||
@ -173,22 +174,27 @@ a {
|
|||||||
|
|
||||||
.navi p {
|
.navi p {
|
||||||
margin: auto 0 auto 0;
|
margin: auto 0 auto 0;
|
||||||
font-size: 2vh;
|
font-size: 1em;
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.naviInner p {
|
.naviInner p {
|
||||||
margin: auto 0 auto 0;
|
margin: auto 0 auto 0;
|
||||||
font-size: 2vh;
|
font-size: 1em;
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mainContainer {
|
#mainContainer {
|
||||||
overflow: hidden;
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
background-color: #3e505a;
|
background-color: #3e505a;
|
||||||
font-family: 'Saira Condensed', sans-serif;
|
font-family: 'Saira Condensed', sans-serif;
|
||||||
grid-column: 2;
|
height: 100%;
|
||||||
grid-row: 2;
|
min-width: 100vh;
|
||||||
|
width: calc(100vw - 30vh);
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
@ -206,25 +212,18 @@ a {
|
|||||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
||||||
}
|
}
|
||||||
|
|
||||||
#songList {
|
|
||||||
height: 100%;
|
|
||||||
color: white;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 100%;
|
|
||||||
grid-template-rows: 90% 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#directory {
|
#directory {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
height: 100%;
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
grid-row: 1;
|
grid-row: 1;
|
||||||
grid-template-columns: 100%;
|
grid-template-columns: 100%;
|
||||||
grid-template-rows: 1fr 2fr 20fr 5fr;
|
grid-template-rows: 1fr 2fr 25fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#directory p {
|
#directory p {
|
||||||
font-size: 150%;
|
font-size: 1.2em;
|
||||||
padding: 1.5vh 2vh 1.5vh 2vh;
|
padding: 0.6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
@ -241,24 +240,31 @@ canvas {
|
|||||||
#directoryHeader {
|
#directoryHeader {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 60% 25% 10% 5%;
|
grid-template-columns: 60% 25% 10% 5%;
|
||||||
grid-template-rows: 100%;
|
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #1c1c1c;
|
background-color: #3c84a7;
|
||||||
box-shadow: #242424 0 0 20px 0px;
|
box-shadow: #242424 0 0 2px 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#directoryHeader p {
|
#directoryHeader p {
|
||||||
display: grid;
|
display: grid;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
grid-template-columns: 19fr 1fr;
|
grid-template-columns: 19fr 1fr;
|
||||||
grid-template-rows: 100%;
|
padding: .6em;
|
||||||
padding: 2.3vh;
|
border-left: 1px solid #fefefe;
|
||||||
|
}
|
||||||
|
|
||||||
|
#directoryHeader p:first-child {
|
||||||
|
border-left: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#directoryHeader p:hover {
|
#directoryHeader p:hover {
|
||||||
background-color: rgba(0,0,0,0.1);
|
background-color: rgba(0,0,0,0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#directoryHeader span {
|
||||||
|
margin: auto 0 auto 0;
|
||||||
|
}
|
||||||
|
|
||||||
#directoryHeader i {
|
#directoryHeader i {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
display: none;
|
display: none;
|
||||||
@ -282,16 +288,26 @@ canvas {
|
|||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item:first-child {
|
||||||
|
border-top: 1px solid #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item:last-child {
|
||||||
|
margin-bottom: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
.item .name {
|
.item .name {
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item .modified {
|
.item .modified {
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
|
padding-left: 1.2em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item .size: {
|
.item .size {
|
||||||
grid-column: 4;
|
grid-column: 4;
|
||||||
|
padding-left: 1.2em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item p {
|
.item p {
|
||||||
@ -299,9 +315,8 @@ canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.item div {
|
.item div {
|
||||||
grid-column: 5;
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
font-size: 140%;
|
font-size: 1.2em;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +333,7 @@ canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.fileIcon .fa {
|
.fileIcon .fa {
|
||||||
padding: 1.3vh;
|
padding: .6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fileIcon .fa:hover {
|
.fileIcon .fa:hover {
|
||||||
103
css/index.css
Normal file
103
css/index.css
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
html, body {
|
||||||
|
min-height: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Roboto Slab', sans-serif;
|
||||||
|
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: grid;
|
||||||
|
background-color: #0e0e0e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transition {
|
||||||
|
-webkit-transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
-moz-transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
-ms-transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer {
|
||||||
|
margin: auto;
|
||||||
|
padding: 2.5em;
|
||||||
|
background-color: #27262b;
|
||||||
|
color: #fefefe;
|
||||||
|
box-shadow: 4px 4px 3px rgba(0, 0, 0, 0.12);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer #formSizeWrapper {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer #formSizeWrapper div {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer h1 {
|
||||||
|
margin: auto auto 10% auto;
|
||||||
|
font-size: 350%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer p {
|
||||||
|
margin: 0 0 2% 0;
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer input {
|
||||||
|
margin-bottom: 10%;
|
||||||
|
padding: 5%;
|
||||||
|
border: none;
|
||||||
|
font-size: 130%;
|
||||||
|
font-family: 'Roboto Slab', sans-serif;
|
||||||
|
display: block;
|
||||||
|
background-color: rgba(255,255,255,0.1);
|
||||||
|
color: #fefefe;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer input[type=password] {
|
||||||
|
margin-bottom: 35%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer input:hover, #formContainer input:active {
|
||||||
|
background-color: rgba(255,255,255,0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer button {
|
||||||
|
width: 100%;
|
||||||
|
font-family: 'Roboto Slab', sans-serif;
|
||||||
|
font-size: 150%;
|
||||||
|
padding: 3%;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 0;
|
||||||
|
background-color: #5fab4c;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 3%;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer button:hover {
|
||||||
|
background-color: #599e48;
|
||||||
|
}
|
||||||
|
|
||||||
|
#formContainer button:active {
|
||||||
|
animation: pop 0.3s cubic-bezier(.25, .8, .25, 1) 0s 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pop {
|
||||||
|
0% { width: 98%; margin: 1%; font-size: 140%; bottom: 2.5%;}
|
||||||
|
100% { width: 100%; margin: 0; font-size: 150%; bottom: 3%;}
|
||||||
|
}
|
||||||
@ -16,7 +16,7 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: white;
|
color: white;
|
||||||
font-family: 'Open Sans Condensed', sans-serif;
|
font-family: 'Saira Condensed', sans-serif;
|
||||||
grid-template-columns: 100%;
|
grid-template-columns: 100%;
|
||||||
grid-template-rows: 8% 6% auto;
|
grid-template-rows: 8% 6% auto;
|
||||||
}
|
}
|
||||||
@ -72,10 +72,6 @@ a {
|
|||||||
box-shadow: 1px 0px 12px 1px black;
|
box-shadow: 1px 0px 12px 1px black;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar div:nth-child(2) {
|
|
||||||
margin-top: 20%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar span {
|
#sidebar span {
|
||||||
font-size: 110%;
|
font-size: 110%;
|
||||||
padding: 5%;
|
padding: 5%;
|
||||||
@ -97,6 +93,16 @@ a {
|
|||||||
grid-template-columns: 1fr 3fr 7fr;
|
grid-template-columns: 1fr 3fr 7fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.naviHead {
|
||||||
|
background-color: rgba(0,0,0,0.4);
|
||||||
|
padding: 3%;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.naviHead:first-child {
|
||||||
|
margin-top: 6vh;
|
||||||
|
}
|
||||||
|
|
||||||
.naviInner {
|
.naviInner {
|
||||||
background-color: rgba(0,0,0,0.15);
|
background-color: rgba(0,0,0,0.15);
|
||||||
}
|
}
|
||||||
@ -123,6 +129,7 @@ a {
|
|||||||
.navi p {
|
.navi p {
|
||||||
margin: auto 0 auto 0;
|
margin: auto 0 auto 0;
|
||||||
font-size: 2vh;
|
font-size: 2vh;
|
||||||
|
font-weight: 300;
|
||||||
grid-column: 3;
|
grid-column: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,9 +175,10 @@ a {
|
|||||||
grid-row: 1;
|
grid-row: 1;
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
font-size: 120%;
|
font-size: 120%;
|
||||||
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item .modified {
|
.item .otherInfo {
|
||||||
grid-row: 2;
|
grid-row: 2;
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
@ -1,74 +0,0 @@
|
|||||||
<body>
|
|
||||||
<div id="header1" class="transition">
|
|
||||||
<h1>BinBin</h1>
|
|
||||||
</div>
|
|
||||||
<div id="header2">
|
|
||||||
<div id="spectrum">
|
|
||||||
<p class="transition">Spectrum <i class="fa fa-times-circle" aria-hidden="true"></i></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="sidebar">
|
|
||||||
<span>Developed by <p onclick="window.open('https://github.com/ksjdragon/binbin.git','_blank')">ksjdragon</p></span>
|
|
||||||
</div>
|
|
||||||
<div id="mainContainer">
|
|
||||||
<div id="songList">
|
|
||||||
<div id="directory">
|
|
||||||
<div id="directoryLocation" class="transition">
|
|
||||||
<p>a</p>
|
|
||||||
</div>
|
|
||||||
<div id="directoryHeader">
|
|
||||||
<p class="name transition">Name
|
|
||||||
<i class="fa fa-chevron-down transition"></i>
|
|
||||||
<i class="fa fa-chevron-up transition"></i>
|
|
||||||
</p>
|
|
||||||
<p class="date transition">Date Modified
|
|
||||||
<i class="fa fa-chevron-down transition"></i>
|
|
||||||
<i class="fa fa-chevron-up transition"></i>
|
|
||||||
</p>
|
|
||||||
<p class="size transition">Size
|
|
||||||
<i class="fa fa-chevron-down transition"></i>
|
|
||||||
<i class="fa fa-chevron-up transition"></i>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div id="directoryCont">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<canvas id="visualize" width="1200" height="250"></canvas>
|
|
||||||
</div>
|
|
||||||
<div id="playback">
|
|
||||||
<div id="info">
|
|
||||||
<div>
|
|
||||||
<h2></h2>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a download><i class="fa fa-download transition"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="tracker">
|
|
||||||
<div>
|
|
||||||
<i id="prev" class="fa fa-step-backward" aria-hidden="true"></i>
|
|
||||||
<i id="pause" class="fa fa-pause-circle transition"></i>
|
|
||||||
<i id="next" class="fa fa-step-forward" aria-hidden="true"></i>
|
|
||||||
</div>
|
|
||||||
<div id="bar">
|
|
||||||
<p>-:--</p>
|
|
||||||
<input type="range" min="0", max="100000" value="0">
|
|
||||||
<p>-:--</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="speed">
|
|
||||||
<i class="fa fa-fast-forward transition"></i>
|
|
||||||
<input type="range" min="0", max="100" value="25">
|
|
||||||
</div>
|
|
||||||
<div id="volume">
|
|
||||||
<i class="fa fa-volume-up transition"></i>
|
|
||||||
<input type="range" min="0", max="100" value="100">
|
|
||||||
</div>
|
|
||||||
<audio controls>
|
|
||||||
<source src="">
|
|
||||||
</audio>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<input id="copy" readonly>
|
|
||||||
</body>
|
|
||||||
@ -1,123 +0,0 @@
|
|||||||
|
|
||||||
var Visualizer = function() {
|
|
||||||
this.file = null, //the current file
|
|
||||||
this.fileName = null, //the current file name
|
|
||||||
this.audioContext = null,
|
|
||||||
this.source = null, //the audio source
|
|
||||||
this.info = document.getElementById('info').innerHTML, //this used to upgrade the UI information
|
|
||||||
this.infoUpdateId = null, //to sotore the setTimeout ID and clear the interval
|
|
||||||
this.animationId = null,
|
|
||||||
this.status = 0, //flag for sound is playing 1 or stopped 0
|
|
||||||
this.forceStop = false,
|
|
||||||
this.allCapsReachBottom = false
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Visualizer.prototype = {
|
|
||||||
ini: function() {
|
|
||||||
this._prepareAPI();
|
|
||||||
},
|
|
||||||
_prepareAPI: function() {
|
|
||||||
//fix browser vender for AudioContext and requestAnimationFrame
|
|
||||||
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
|
|
||||||
window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
|
|
||||||
window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame;
|
|
||||||
try {
|
|
||||||
this.audioContext = new AudioContext();
|
|
||||||
} catch (e) {
|
|
||||||
alert('!Your browser does not support AudioContext', false);
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_visualize: function(url, canvas, audio) {
|
|
||||||
var audioContext = this.audioContext,
|
|
||||||
audioBufferSouceNode = audioContext.createMediaElementSource(audio),
|
|
||||||
analyser = audioContext.createAnalyser(),
|
|
||||||
that = this;
|
|
||||||
this.analyser = analyser;
|
|
||||||
this.canvas = canvas;
|
|
||||||
//connect the source to the analyser
|
|
||||||
audioBufferSouceNode.connect(analyser);
|
|
||||||
//connect the analyser to the destination(the speaker), or we won't hear the sound
|
|
||||||
analyser.connect(audioContext.destination);
|
|
||||||
//then assign the buffer to the buffer source node
|
|
||||||
//play the source
|
|
||||||
if (!audioBufferSouceNode.start) {
|
|
||||||
audioBufferSouceNode.start = audioBufferSouceNode.noteOn //in old browsers use noteOn method
|
|
||||||
audioBufferSouceNode.stop = audioBufferSouceNode.noteOff //in old browsers use noteOn method
|
|
||||||
};
|
|
||||||
//stop the previous sound if any
|
|
||||||
if (this.animationId !== null) {
|
|
||||||
cancelAnimationFrame(this.animationId);
|
|
||||||
}
|
|
||||||
if (this.source !== null) {
|
|
||||||
this.source.stop(0);
|
|
||||||
}
|
|
||||||
//audioBufferSouceNode.start(0);
|
|
||||||
this.status = 1;
|
|
||||||
this.source = audioBufferSouceNode;
|
|
||||||
this._drawSpectrum(analyser, canvas);
|
|
||||||
},
|
|
||||||
_restart: function() {
|
|
||||||
this._drawSpectrum(this.analyser, this.canvas);
|
|
||||||
},
|
|
||||||
_stop: function() {
|
|
||||||
cancelAnimationFrame(this.animationId);
|
|
||||||
},
|
|
||||||
_drawSpectrum: function(analyser, canvas) {
|
|
||||||
var that = this,
|
|
||||||
monoL = canvas,
|
|
||||||
//monoR = document.getElementById('mono-R'),
|
|
||||||
cwidth = monoL.width,
|
|
||||||
cheight = monoL.height - 3,
|
|
||||||
meterWidth = 1, //width of the meters in the spectrum
|
|
||||||
gap = 0.01, //gap between meters
|
|
||||||
capHeight = 2,
|
|
||||||
capStyle = '#fff',
|
|
||||||
meterNum = 20 * (2 + 2), //count of the meters
|
|
||||||
capYPositionArray = []; ////store the vertical position of hte caps for the preivous frame
|
|
||||||
ctx = monoL.getContext('2d'),
|
|
||||||
gradient = ctx.createLinearGradient(0, 0, 0, 300);
|
|
||||||
gradient.addColorStop(1, themeColors.highlight);
|
|
||||||
gradient.addColorStop(0, '#fff');
|
|
||||||
|
|
||||||
var drawMeter = function() {
|
|
||||||
var array = new Uint8Array(analyser.frequencyBinCount);
|
|
||||||
analyser.getByteFrequencyData(array);
|
|
||||||
if (that.status === 0) {
|
|
||||||
//fix when some sounds end the value still not back to zero
|
|
||||||
for (var i = array.length - 1; i >= 0; i--) {
|
|
||||||
array[i] = 0;
|
|
||||||
};
|
|
||||||
allCapsReachBottom = true;
|
|
||||||
for (var i = capYPositionArray.length - 1; i >= 0; i--) {
|
|
||||||
allCapsReachBottom = allCapsReachBottom && (capYPositionArray[i] === 0);
|
|
||||||
};
|
|
||||||
if (allCapsReachBottom) {
|
|
||||||
cancelAnimationFrame(that.animationId); //since the sound is top and animation finished, stop the requestAnimation to prevent potential memory leak,THIS IS VERY IMPORTANT!
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
var step = Math.round(array.length / meterNum); //sample limited data from the total array
|
|
||||||
ctx.clearRect(0, 0, cwidth, cheight);
|
|
||||||
for (var i = 0; i < meterNum; i++) {
|
|
||||||
var value = array[i * step];
|
|
||||||
if (capYPositionArray.length < Math.round(meterNum)) {
|
|
||||||
capYPositionArray.push(value);
|
|
||||||
};
|
|
||||||
ctx.fillStyle = capStyle;
|
|
||||||
//draw the cap, with transition effect
|
|
||||||
if (value < capYPositionArray[i]) {
|
|
||||||
ctx.fillRect(i * 12, cheight - (--capYPositionArray[i]), meterWidth, capHeight);
|
|
||||||
} else {
|
|
||||||
ctx.fillRect(i * 12, cheight - value, meterWidth, capHeight);
|
|
||||||
capYPositionArray[i] = value;
|
|
||||||
};
|
|
||||||
ctx.fillStyle = gradient; //set the filllStyle to gradient for a better look
|
|
||||||
ctx.fillRect(i * 12 /*meterWidth+gap*/ , cheight - value + capHeight, meterWidth, cheight); //the meter
|
|
||||||
}
|
|
||||||
that.animationId = requestAnimationFrame(drawMeter);
|
|
||||||
}
|
|
||||||
this.animationId = requestAnimationFrame(drawMeter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
33
download.php
33
download.php
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
$dir = $_GET['name'];
|
|
||||||
$unlnk = $_GET['u'];
|
|
||||||
$file_url = getcwd().$dir;
|
|
||||||
$type = mime_content_type($dir);
|
|
||||||
|
|
||||||
header('Content-Description: File Transfer');
|
|
||||||
header('Content-Type: '.$type);
|
|
||||||
header("Content-Disposition: attachment; filename=\"" . basename($file_url) . "\"");
|
|
||||||
header('Content-Transfer-Encoding: Binary');
|
|
||||||
header('Expires: 0');
|
|
||||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
|
||||||
header('Pragma: public');
|
|
||||||
header('Content-Length: ' . filesize($file_url));
|
|
||||||
|
|
||||||
ob_clean();
|
|
||||||
ob_end_flush();
|
|
||||||
$handle = fopen($file_url, "rb");
|
|
||||||
|
|
||||||
if($unlnk === "y") {
|
|
||||||
ignore_user_abort(true);
|
|
||||||
while (!feof($handle)) {
|
|
||||||
echo fread($handle, 1000);
|
|
||||||
}
|
|
||||||
unlink($file_url);
|
|
||||||
} else {
|
|
||||||
while (!feof($handle)) {
|
|
||||||
echo fread($handle, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
39
index.html
39
index.html
@ -1,39 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
|
||||||
<title>BinBin</title>
|
|
||||||
<link rel="icon" href="favicon.ico?v=2">
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300" rel="stylesheet">
|
|
||||||
<link href="https://fonts.googleapis.com/css?family=Saira+Condensed:300,400" rel="stylesheet">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
|
||||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script></script>
|
|
||||||
<script src="https://use.fontawesome.com/c8d5486cd8.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
var prefix = (screen.width <= 699) ? "mobile" : "desktop";
|
|
||||||
var scripts = {
|
|
||||||
"desktop": ["visualizer", "desktop"],
|
|
||||||
"mobile": ["mobile"]
|
|
||||||
};
|
|
||||||
var l = document.createElement("link");
|
|
||||||
l.rel = "stylesheet";
|
|
||||||
l.href = "./"+prefix+"/"+prefix+".css";
|
|
||||||
document.getElementsByTagName("head")[0].appendChild(l);
|
|
||||||
$.ajax({
|
|
||||||
type:"GET",
|
|
||||||
url:window.location.origin + "/"+prefix+"/"+prefix+".html",
|
|
||||||
success: function(d){
|
|
||||||
document.getElementsByTagName("body")[0].outerHTML = d;
|
|
||||||
for(var i = 0; i < scripts[prefix].length; i++) {
|
|
||||||
var s = document.createElement("script");
|
|
||||||
s.src = "./"+prefix+"/"+scripts[prefix][i]+".js";
|
|
||||||
document.getElementsByTagName("html")[0].appendChild(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</html>
|
|
||||||
38
js/alert.js
Normal file
38
js/alert.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Loads alert box into HTML first.
|
||||||
|
|
||||||
|
var box = document.createElement("div");
|
||||||
|
var p = document.createElement("p");
|
||||||
|
|
||||||
|
box.id = "alert";
|
||||||
|
box.style.position = "absolute";
|
||||||
|
box.style.top = "-4em";
|
||||||
|
box.style.width = "100%";
|
||||||
|
box.style.color = "#fefefe";
|
||||||
|
box.style.textAlign = "center";
|
||||||
|
|
||||||
|
box.style.setProperty("-webkit-transition", " top 0.3s cubic-bezier(.25, .8, .25, 1)");
|
||||||
|
box.style.setProperty("transition:", "top 0.3s cubic-bezier(.25, .8, .25, 1)");
|
||||||
|
box.style.setProperty("-moz-transition", " top 0.3s cubic-bezier(.25, .8, .25, 1)");
|
||||||
|
box.style.setProperty("-ms-transition", " top 0.3s cubic-bezier(.25, .8, .25, 1)");
|
||||||
|
|
||||||
|
p.style.backgroundColor = "#000";
|
||||||
|
p.style.display = "inline";
|
||||||
|
p.style.padding = "1em";
|
||||||
|
p.style.borderRadius = "4px";
|
||||||
|
|
||||||
|
box.appendChild(p);
|
||||||
|
|
||||||
|
get("body").appendChild(box);
|
||||||
|
|
||||||
|
function alertBox(s, type) {
|
||||||
|
colors = {
|
||||||
|
"error": "#d24242",
|
||||||
|
"msg": "#4d9e53"
|
||||||
|
};
|
||||||
|
box.childNodes[0].textContent = s;
|
||||||
|
box.childNodes[0].style.backgroundColor = colors[type];
|
||||||
|
box.style.top = "2em";
|
||||||
|
setTimeout(function() {
|
||||||
|
box.style.top = "-4em";
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
234
js/desktop.js
Normal file
234
js/desktop.js
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
var data = [[],[]] // Stores file directory data.
|
||||||
|
var navi = { // Stores data for sidebar navigation.
|
||||||
|
'owned': [],
|
||||||
|
'shared': []
|
||||||
|
};
|
||||||
|
var drives = {}; // Stores drive names.
|
||||||
|
var navSelect; // Stores current selected sidebar option.
|
||||||
|
var clickable = true; // Prevents actions being run more than once.
|
||||||
|
var selectDiv; // Stores selected file or folder div.
|
||||||
|
var currDir = ''; // Stores the current directory.
|
||||||
|
|
||||||
|
// FIX THE DATE
|
||||||
|
function sortFiles(type, direction) {
|
||||||
|
if(type === 'name') data[0] = sortSection(type, direction, data[0]);
|
||||||
|
data[1] = sortSection(type, direction, data[1]);
|
||||||
|
|
||||||
|
ico = get('#directoryHeader i');
|
||||||
|
ico.forEach(function(ele) {
|
||||||
|
ele.style.opacity = '0';
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
ico.forEach(function(ele) {
|
||||||
|
ele.style.display = 'none';
|
||||||
|
});
|
||||||
|
var arrow = (direction < 0) ? 'up' : 'down';
|
||||||
|
arrow = get(`#directoryHeader .${type} i.fa-chevron-${arrow}`);
|
||||||
|
animFade('open', arrow);
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
try {
|
||||||
|
clearTbl();
|
||||||
|
setTimeout(function() {
|
||||||
|
get('#directory').removeChild(get('#directoryCont'));
|
||||||
|
dispDir();
|
||||||
|
}, 300);
|
||||||
|
} catch(err) {
|
||||||
|
dispDir();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function dispDir() {
|
||||||
|
updateLocation();
|
||||||
|
try {
|
||||||
|
get('#directory').removeChild(get('#directoryCont'));
|
||||||
|
} catch(err) {}
|
||||||
|
|
||||||
|
var cont = element('div', {
|
||||||
|
id: 'directoryCont',
|
||||||
|
class: 'transition',
|
||||||
|
style: 'opacity:0'
|
||||||
|
});
|
||||||
|
|
||||||
|
if(data[0].length === 0 && data[1].length === 0) {
|
||||||
|
cont.appendChild(element('p', {
|
||||||
|
text: 'Nothing here!',
|
||||||
|
style: 'font-weight: 100'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < data.length; i++) {
|
||||||
|
for(var j = 0; j < data[i].length; j++) {
|
||||||
|
var itemInfo = data[i][j];
|
||||||
|
|
||||||
|
var ext = (itemInfo.folder) ? "fol" :
|
||||||
|
itemInfo.name.substring(
|
||||||
|
itemInfo.name.lastIndexOf(".") + 1,
|
||||||
|
itemInfo.name.length)
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
|
var item = element('div', {
|
||||||
|
class: 'item transition',
|
||||||
|
ext: ext,
|
||||||
|
filename: itemInfo.name
|
||||||
|
});
|
||||||
|
|
||||||
|
item.appendChild(element('p', {
|
||||||
|
class: 'name',
|
||||||
|
text: itemInfo.name
|
||||||
|
}));
|
||||||
|
|
||||||
|
item.appendChild(element('p', {
|
||||||
|
class: 'modified',
|
||||||
|
text: (itemInfo.folder) ? "----" : dateStr(itemInfo.date)
|
||||||
|
}));
|
||||||
|
|
||||||
|
item.appendChild(element('p', {
|
||||||
|
class: 'size',
|
||||||
|
text: itemInfo.size || "----"
|
||||||
|
}));
|
||||||
|
|
||||||
|
if(!itemInfo.folder) {
|
||||||
|
var a = element('div', {
|
||||||
|
onclick: function() {
|
||||||
|
console.log("generating download link");
|
||||||
|
// DO EXPIRY LINKS HERE
|
||||||
|
// update link to get('copy') and copy
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
a.appendChild(element('i', {
|
||||||
|
class: 'fa fa-files-o transition'
|
||||||
|
}));
|
||||||
|
|
||||||
|
item.appendChild(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ico = element('div', {
|
||||||
|
class: 'fileIcon',
|
||||||
|
});
|
||||||
|
|
||||||
|
ico.appendChild(element('i', {
|
||||||
|
class: `fa fa-${(faIcons[ext] || faIcons["other"])}`
|
||||||
|
}));
|
||||||
|
|
||||||
|
item.appendChild(ico);
|
||||||
|
|
||||||
|
item.onclick = function() {
|
||||||
|
if(!clickable) return;
|
||||||
|
// DO WITH SHIFT AND CONTROL LATER.
|
||||||
|
|
||||||
|
if(this.className.search( 'selectedItem') === -1) {
|
||||||
|
get('.item').forEach(function(ele) {
|
||||||
|
ele.style.backgroundColor = "";
|
||||||
|
ele.className = ele.className.replace(' selectedItem',
|
||||||
|
'');
|
||||||
|
});
|
||||||
|
this.className += ' selectedItem';
|
||||||
|
this.style.backgroundColor = "rgba(255,255,255,0.2)";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Below executes only after user has clicked twice.
|
||||||
|
var name = this.getAttribute('filename');
|
||||||
|
var ext = this.getAttribute('ext');
|
||||||
|
|
||||||
|
clickable = false;
|
||||||
|
if(ext == 'fol') {
|
||||||
|
clearTbl();
|
||||||
|
setTimeout(function() {
|
||||||
|
currDir += '/' + name;
|
||||||
|
listDir(currDir, 0);
|
||||||
|
}, 300);
|
||||||
|
} else {
|
||||||
|
downloadFile(currDir + "/" + name);
|
||||||
|
}
|
||||||
|
clickable = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
cont.appendChild(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get('#directory').appendChild(cont);
|
||||||
|
setTimeout(function() {
|
||||||
|
get('#directoryCont').style.opacity = "1";
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateLocation() {
|
||||||
|
var loc = get('#directoryLocation');
|
||||||
|
while(loc.firstChild) loc.removeChild(loc.firstChild);
|
||||||
|
loc.style.opacity = '1';
|
||||||
|
var subdir = currDir.split('/');
|
||||||
|
|
||||||
|
for(var i = 0; i < subdir.length; i++) {
|
||||||
|
var p = element('p', {
|
||||||
|
text: (i === 0) ? drives[navSelect] : subdir[i],
|
||||||
|
class: 'subdir transition',
|
||||||
|
style: 'cursor:pointer',
|
||||||
|
onclick: function() {
|
||||||
|
clickable = false;
|
||||||
|
clearTbl();
|
||||||
|
subdirNum = subdir.indexOf(this.innerText);
|
||||||
|
if(subdirNum === -1) {
|
||||||
|
currDir = '';
|
||||||
|
} else {
|
||||||
|
currDir = subdir.slice(0, subdirNum+1)
|
||||||
|
.reduce(function(a,b) { return a + '/' + b; }) + '/';
|
||||||
|
}
|
||||||
|
listDir(currDir, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(i > 0) {
|
||||||
|
loc.appendChild(element('i', {
|
||||||
|
class: 'fa fa-angle-right'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
loc.appendChild(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function sortButtons() {
|
||||||
|
get('#directoryHeader .name').onclick = function() {
|
||||||
|
sort.name = sort.name * -1;
|
||||||
|
sortFiles('name', sort.name);
|
||||||
|
};
|
||||||
|
get('#directoryHeader .date').onclick = function() {
|
||||||
|
sort.date = sort.date * -1;
|
||||||
|
sortFiles('date', sort.date);
|
||||||
|
};
|
||||||
|
get('#directoryHeader .size').onclick = function() {
|
||||||
|
sort.size = sort.size * -1;
|
||||||
|
sortFiles('size', sort.size);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('keydown', function(event) {
|
||||||
|
try {
|
||||||
|
switch((event || window.event).keyCode) {
|
||||||
|
case 13:
|
||||||
|
selectDiv.click();
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
selectDiv.previousElementSibling.click();
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
if(selectDiv == undefined) {
|
||||||
|
document.getElementById('directoryCont').childNodes[0].click();
|
||||||
|
} else {
|
||||||
|
selectDiv.nextElementSibling.click();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
var subdirs = document.getElementsByClassName('subdir');
|
||||||
|
subdirs[subdirs.length-1].click();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch(err) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
getDrives();
|
||||||
|
sortButtons();
|
||||||
0
js/drive.js
Normal file
0
js/drive.js
Normal file
98
js/index.js
Normal file
98
js/index.js
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
var t = 0;
|
||||||
|
|
||||||
|
function login(form) {
|
||||||
|
u = form.username.value;
|
||||||
|
p = form.password.value;
|
||||||
|
uEmpty = u === "", pEmpty = p === "";
|
||||||
|
|
||||||
|
if(uEmpty && pEmpty) {
|
||||||
|
alertBox("Please enter a username and password!", "error");
|
||||||
|
return;
|
||||||
|
} else if (uEmpty && !pEmpty) {
|
||||||
|
alertBox("Please enter a username!", "error");
|
||||||
|
return;
|
||||||
|
} else if (!uEmpty && pEmpty) {
|
||||||
|
alertBox("Please enter a password!", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {username: u, password: p}
|
||||||
|
$.post("./login", data).done(function(data) {
|
||||||
|
if(data) {
|
||||||
|
location.reload(true);
|
||||||
|
} else {
|
||||||
|
alertBox("Wrong username or password!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawCanvas() {
|
||||||
|
var el = get("canvas")
|
||||||
|
var c = el.getContext("2d")
|
||||||
|
var block = 10, space = 2, size = block+space;
|
||||||
|
var period = 100, freq = 2*Math.PI/period, step = 1.4, base = 0.05;
|
||||||
|
|
||||||
|
var col = randColor();
|
||||||
|
var dir = randDir();
|
||||||
|
|
||||||
|
function animCanvas(t, col) {
|
||||||
|
// To update when window changes.
|
||||||
|
var w = window.innerWidth, h = window.innerHeight;
|
||||||
|
var x = w/size, y = h/size;
|
||||||
|
var offX = -(w-Math.floor(x)*size)/2, offY = -(h-Math.floor(y)*size)/2;
|
||||||
|
|
||||||
|
el.width = w, el.height = h;
|
||||||
|
|
||||||
|
|
||||||
|
c.fillStyle = "#0e0e0e";
|
||||||
|
c.fillRect(0, 0, w, h);
|
||||||
|
for(var i = 0; i < x+1; i++) {
|
||||||
|
for(var j = 0; j < y+1; j++) {
|
||||||
|
var intes = Math.round(step*Math.cos((i+j*dir[0]+t*dir[1])*freq)+step)*0.2/step+base
|
||||||
|
c.fillStyle = `rgba(${col[0]},${col[1]},${col[2]},${intes})`;
|
||||||
|
c.fillRect(i*size+offX, j*size+offY, block, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function randColor() {
|
||||||
|
var arr = [
|
||||||
|
128*Math.round(2*Math.random())-1,
|
||||||
|
128*Math.round(2*Math.random())-1,
|
||||||
|
128*Math.round(2*Math.random())-1
|
||||||
|
];
|
||||||
|
while(arr[0]+arr[1]+arr[2] < 382) arr = randColor();
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function randDir() {
|
||||||
|
return [
|
||||||
|
(Math.round(Math.random())) ? -1 : 1,
|
||||||
|
(Math.round(Math.random())) ? -1 : 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
t += animCanvas(t, col);
|
||||||
|
if(t == period) {
|
||||||
|
t = 0;
|
||||||
|
newCol = randColor();
|
||||||
|
while(newCol === col) newCol == randColor();
|
||||||
|
col = newCol;
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawCanvas();
|
||||||
|
|
||||||
|
inputs = get("input"), button = get("button")
|
||||||
|
|
||||||
|
inputs[0].addEventListener("keyup", function(e) {
|
||||||
|
if(e.keyCode === 13) button.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
inputs[1].addEventListener("keyup", function(e) {
|
||||||
|
if(e.keyCode === 13) button.click();
|
||||||
|
});
|
||||||
290
js/mobile.js
Normal file
290
js/mobile.js
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
var data = [[],[]] // Stores file directory data.
|
||||||
|
var navi = { // Stores data for sidebar navigation.
|
||||||
|
'owned': [],
|
||||||
|
'shared': []
|
||||||
|
};
|
||||||
|
var drives = {}; // Stores drive names.
|
||||||
|
var navSelect; // Stores current selected sidebar option.
|
||||||
|
var clickable = true; // Prevents actions being run more than once.
|
||||||
|
var selectDiv; // Stores selected file or folder div.
|
||||||
|
var currDir = ''; // Stores the current directory.
|
||||||
|
|
||||||
|
function sortFiles(type, direction) {
|
||||||
|
if(type === 'name') data[0] = sortSection(type, direction, data[0]);
|
||||||
|
data[1] = sortSection(type, direction, data[1]);
|
||||||
|
|
||||||
|
var p = get('#sortType');
|
||||||
|
var i = get('#sortDirection');
|
||||||
|
p.style.opacity = '0';
|
||||||
|
i.style.opacity = '0';
|
||||||
|
p.innerText = type[0].toUpperCase() + type.substring(1, type.length);
|
||||||
|
setTimeout(function() {
|
||||||
|
var arrow = (direction < 0) ? 'up' : 'down';
|
||||||
|
i.className = `fa fa-arrow-${arrow} transition`;
|
||||||
|
p.style.opacity = '1';
|
||||||
|
i.style.opacity = '1';
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
try {
|
||||||
|
clearTbl();
|
||||||
|
setTimeout(function() {
|
||||||
|
get('#directory').removeChild(get('#directoryCont'));
|
||||||
|
dispDir();
|
||||||
|
}, 300);
|
||||||
|
} catch(err) {
|
||||||
|
dispDir();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function dispDir() {
|
||||||
|
updateLocation();
|
||||||
|
try {
|
||||||
|
get('#directory').removeChild(get('#directoryCont'));
|
||||||
|
} catch(err) {}
|
||||||
|
|
||||||
|
var cont = element('div', {
|
||||||
|
id: 'directoryCont',
|
||||||
|
class: 'transition',
|
||||||
|
style: 'opacity:0'
|
||||||
|
});
|
||||||
|
|
||||||
|
if(data[0].length === 0 && data[1].length === 0) {
|
||||||
|
cont.appendChild(element('p', {
|
||||||
|
text: 'Nothing here!',
|
||||||
|
style: 'font-weight: 100'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i = 0; i < data.length; i++) {
|
||||||
|
for(var j = 0; j < data[i].length; j++) {
|
||||||
|
|
||||||
|
|
||||||
|
var itemInfo = data[i][j];
|
||||||
|
|
||||||
|
var ext = (itemInfo.folder) ? 'fol' :
|
||||||
|
itemInfo.name.substring(
|
||||||
|
itemInfo.name.lastIndexOf('.') + 1,
|
||||||
|
itemInfo.name.length)
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
|
var item = element('div', {
|
||||||
|
class: 'item transition',
|
||||||
|
ext: ext,
|
||||||
|
filename: itemInfo.name
|
||||||
|
});
|
||||||
|
|
||||||
|
item.appendChild(element('p', {
|
||||||
|
class: 'name',
|
||||||
|
text: itemInfo.name
|
||||||
|
}));
|
||||||
|
|
||||||
|
item.appendChild(element('p', {
|
||||||
|
class: 'otherInfo',
|
||||||
|
text: (itemInfo.folder) ? '----' :
|
||||||
|
dateStr(itemInfo.date, 'date') + ' | ' + itemInfo.size
|
||||||
|
}));
|
||||||
|
|
||||||
|
if(!itemInfo.folder) {
|
||||||
|
var a = element('div', {
|
||||||
|
onclick: function() {
|
||||||
|
console.log('generating download link');
|
||||||
|
// DO EXPIRY LINKS HERE
|
||||||
|
// update link to get('copy') and copy
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
a.appendChild(element('i', {
|
||||||
|
class: 'fa fa-files-o transition'
|
||||||
|
}));
|
||||||
|
|
||||||
|
item.appendChild(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ico = element('div', {
|
||||||
|
class: 'fileIcon',
|
||||||
|
});
|
||||||
|
|
||||||
|
ico.appendChild(element('i', {
|
||||||
|
class: `fa fa-${(faIcons[ext] || faIcons['other'])}`
|
||||||
|
}));
|
||||||
|
|
||||||
|
item.appendChild(ico);
|
||||||
|
|
||||||
|
item.onclick = function() {
|
||||||
|
if(!clickable) return;
|
||||||
|
// DO WITH SHIFT AND CONTROL LATER.
|
||||||
|
|
||||||
|
if(this.className.search( 'selectedItem') === -1) {
|
||||||
|
get('.item').forEach(function(ele) {
|
||||||
|
ele.style.backgroundColor = '';
|
||||||
|
ele.className = ele.className.replace(' selectedItem',
|
||||||
|
'');
|
||||||
|
});
|
||||||
|
this.className += ' selectedItem';
|
||||||
|
this.style.backgroundColor = 'rgba(255,255,255,0.2)';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Below executes only after user has clicked twice.
|
||||||
|
var name = this.getAttribute('filename');
|
||||||
|
var ext = this.getAttribute('ext');
|
||||||
|
|
||||||
|
clickable = false;
|
||||||
|
if(ext == 'fol') {
|
||||||
|
clearTbl();
|
||||||
|
setTimeout(function() {
|
||||||
|
currDir += '/' + name;
|
||||||
|
listDir(currDir, 0);
|
||||||
|
}, 300);
|
||||||
|
} else {
|
||||||
|
downloadFile(currDir + '/' + name);
|
||||||
|
}
|
||||||
|
clickable = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
cont.appendChild(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get('#directory').appendChild(cont);
|
||||||
|
setTimeout(function() {
|
||||||
|
get('#directoryCont').style.opacity = '1';
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateLocation() {
|
||||||
|
var i = get('#barOpen i');
|
||||||
|
if(currDir === '') {
|
||||||
|
get('#location').textContent = drives[navSelect];
|
||||||
|
if(i.className.includes('fa-bars')) return;
|
||||||
|
i.style.opacity = '0';
|
||||||
|
setTimeout(function() {
|
||||||
|
i.className = 'fa fa-bars transition';
|
||||||
|
i.style.opacity = '1'
|
||||||
|
}, 300);
|
||||||
|
} else {
|
||||||
|
get('#location').textContent = currDir.split('/').slice(-1);
|
||||||
|
if(i.className.includes('fa-arrow-left')) return;
|
||||||
|
i.style.opacity = '0';
|
||||||
|
setTimeout(function() {
|
||||||
|
i.className = 'fa fa-arrow-left transition';
|
||||||
|
i.style.opacity = '1';
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function sortButtons() {
|
||||||
|
get('#sortText').onclick = function() {
|
||||||
|
event.stopPropagation();
|
||||||
|
};
|
||||||
|
|
||||||
|
get('#sortName').onclick = function() {
|
||||||
|
event.stopPropagation();
|
||||||
|
animMenu('close');
|
||||||
|
sort.name = sort.name * -1;
|
||||||
|
sortFiles('name', sort.name);
|
||||||
|
};
|
||||||
|
|
||||||
|
get('#sortDate').onclick = function() {
|
||||||
|
event.stopPropagation();
|
||||||
|
animMenu('close');
|
||||||
|
sort.date = sort.date * -1;
|
||||||
|
sortFiles('date', sort.date);
|
||||||
|
};
|
||||||
|
|
||||||
|
get('#sortSize').onclick = function() {
|
||||||
|
event.stopPropagation();
|
||||||
|
animMenu('close');
|
||||||
|
sort.size = sort.size * -1;
|
||||||
|
sortFiles('size', sort.size);
|
||||||
|
};
|
||||||
|
|
||||||
|
get('#sortType').onclick = function() {
|
||||||
|
var type = this.innerText.toLowerCase();
|
||||||
|
sort[type] = sort[type] * -1;
|
||||||
|
sortFiles(type, sort[type]);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
get('#barOpen').onclick = function() {
|
||||||
|
animIcon(this);
|
||||||
|
if(currDir === '') {
|
||||||
|
setTimeout(function() {
|
||||||
|
moveSidebar('open');
|
||||||
|
}, 10);
|
||||||
|
} else {
|
||||||
|
var arr = currDir.split('/');
|
||||||
|
if(arr.length === 2) {
|
||||||
|
currDir = '';
|
||||||
|
} else {
|
||||||
|
currDir = arr.slice(0, -1).reduce((a,b) => a + '/' + b);
|
||||||
|
}
|
||||||
|
listDir(currDir, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function animMenu(type) {
|
||||||
|
if(type === 'open') {
|
||||||
|
animFade('open', get('#menuOverlay'));
|
||||||
|
setTimeout(function() {
|
||||||
|
get('#optionContainer').style.bottom = '0';
|
||||||
|
}, 150);
|
||||||
|
} else if(type === 'close') {
|
||||||
|
animFade('close', get('#menuOverlay'));
|
||||||
|
get('#optionContainer').style.bottom = '-60%';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function moveSidebar(type) {
|
||||||
|
if(type === 'open') {
|
||||||
|
get('#sidebar').style.left = '0';
|
||||||
|
} else if(type === 'close') {
|
||||||
|
get('#sidebar').style.left = '-80%';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function animIcon(div) {
|
||||||
|
div.children[0].style.backgroundColor = 'rgba(0,0,0,0.2)';
|
||||||
|
setTimeout(function() {
|
||||||
|
div.children[0].style.backgroundColor = 'rgba(0,0,0,0)';
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
function darkenTap(div) {
|
||||||
|
div.style.backgroundColor = 'rgba(0,0,0,0.2)';
|
||||||
|
that = this;
|
||||||
|
setTimeout(function() {
|
||||||
|
div.style.backgroundColor = 'rgba(0,0,0,0)';
|
||||||
|
}, 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
get('#sidebar').onclick = function() {
|
||||||
|
event.stopPropagation();
|
||||||
|
};
|
||||||
|
|
||||||
|
get('#dotOpen').onclick = function(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
animIcon(this);
|
||||||
|
animFade('open', get('#dotMenu'));
|
||||||
|
};
|
||||||
|
|
||||||
|
get('#openSort').onclick = function() {
|
||||||
|
event.stopPropagation();
|
||||||
|
darkenTap(this);
|
||||||
|
animFade('close', get('#dotMenu'));
|
||||||
|
animMenu('open');
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById('download').onclick = function() {
|
||||||
|
event.stopPropagation();
|
||||||
|
darkenTap(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.onclick = function(event) {
|
||||||
|
animFade('close', get('#dotMenu'));
|
||||||
|
animMenu('close');
|
||||||
|
moveSidebar('close');
|
||||||
|
};
|
||||||
|
|
||||||
|
getDrives();
|
||||||
|
sortButtons();
|
||||||
100
js/overlay.temp.js
Normal file
100
js/overlay.temp.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
function videoOverlay(url) {
|
||||||
|
var overlay = getDefaultOverlay();
|
||||||
|
|
||||||
|
var video = document.createElement("video");
|
||||||
|
video.onclick = function() {event.stopPropagation();}
|
||||||
|
video.src = url;
|
||||||
|
video.controls = true;
|
||||||
|
video.autoplay = true;
|
||||||
|
video.type = "video/mp4";
|
||||||
|
|
||||||
|
video.style.margin = "auto";
|
||||||
|
video.style.backgroundColor = "black";
|
||||||
|
|
||||||
|
video.onloadedmetadata = function() {
|
||||||
|
if((video.videoHeight/video.videoWidth) > (window.innerHeight/window.innerWidth)) {
|
||||||
|
video.style.height = (window.innerHeight * 0.9).toString() + "px";
|
||||||
|
} else {
|
||||||
|
video.style.width = (window.innerWidth * 0.9).toString() + "px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var div = document.createElement("div");
|
||||||
|
div.style.margin = "auto";
|
||||||
|
div.style.gridRow = "1";
|
||||||
|
div.style.gridColumn = "1";
|
||||||
|
div.appendChild(video);
|
||||||
|
overlay.appendChild(div);
|
||||||
|
|
||||||
|
var close = getClose();
|
||||||
|
overlay.appendChild(close);
|
||||||
|
|
||||||
|
document.getElementsByTagName("body")[0].appendChild(overlay);
|
||||||
|
setTimeout(function() {
|
||||||
|
overlay.style.opacity = "1";
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
function audioOverlay(url) {
|
||||||
|
var overlay = getDefaultOverlay();
|
||||||
|
var audio = document.createElement("audio");
|
||||||
|
audio.onclick = function() {event.stopPropagation();}
|
||||||
|
audio.src = url;
|
||||||
|
audio.controls = true;
|
||||||
|
audio.autoplay = true;
|
||||||
|
|
||||||
|
audio.style.margin = "auto";
|
||||||
|
audio.style.width = (window.innerWidth * 0.9).toString() + "px";
|
||||||
|
|
||||||
|
var div = document.createElement("div");
|
||||||
|
div.style.margin = "auto";
|
||||||
|
div.style.gridRow = "1";
|
||||||
|
div.style.gridColumn = "1";
|
||||||
|
div.appendChild(audio);
|
||||||
|
overlay.appendChild(div);
|
||||||
|
|
||||||
|
var close = getClose();
|
||||||
|
overlay.appendChild(close);
|
||||||
|
|
||||||
|
document.getElementsByTagName("body")[0].appendChild(overlay);
|
||||||
|
setTimeout(function() {
|
||||||
|
overlay.style.opacity = "1";
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function imageOverlay(url) {
|
||||||
|
var overlay = getDefaultOverlay();
|
||||||
|
var img = new Image();
|
||||||
|
img.src = url;
|
||||||
|
img.style.margin = "auto";
|
||||||
|
|
||||||
|
var image = document.createElement("img");
|
||||||
|
image.src = url;
|
||||||
|
img.onload = function() {
|
||||||
|
var height = img.height;
|
||||||
|
var width = img.width;
|
||||||
|
|
||||||
|
|
||||||
|
if((height/width) > (window.innerHeight/window.innerWidth)) {
|
||||||
|
image.style.height = (window.innerHeight * 0.9).toString() + "px";
|
||||||
|
} else {
|
||||||
|
image.style.width = (window.innerWidth * 0.9).toString() + "px";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var div = document.createElement("div");
|
||||||
|
div.style.margin = "auto";
|
||||||
|
div.style.gridRow = "1";
|
||||||
|
div.style.gridColumn = "1";
|
||||||
|
div.appendChild(image);
|
||||||
|
overlay.appendChild(div);
|
||||||
|
|
||||||
|
var close = getClose();
|
||||||
|
overlay.appendChild(close);
|
||||||
|
|
||||||
|
document.getElementsByTagName("body")[0].appendChild(overlay);
|
||||||
|
setTimeout(function() {
|
||||||
|
overlay.style.opacity = "1";
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
203
js/tools.js
Normal file
203
js/tools.js
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
var themeColors = { // For reference and for quick changing if need-be.
|
||||||
|
'main': '#3e505a',
|
||||||
|
'sidebar': '#2a2e31',
|
||||||
|
'highlight': '#fff'
|
||||||
|
};
|
||||||
|
|
||||||
|
var faIcons = {
|
||||||
|
'fol': 'folder',
|
||||||
|
'mp3': 'music',
|
||||||
|
'ogg': 'music',
|
||||||
|
'mp4': 'video-camera',
|
||||||
|
'zip': 'file-zip-o',
|
||||||
|
'other': 'file-o'
|
||||||
|
};
|
||||||
|
|
||||||
|
var sort = { // Default sorting directions.
|
||||||
|
'name': -1,
|
||||||
|
'date': 1,
|
||||||
|
'size': 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
var navi = [ // Necessary arguments: id, alias, fa | Optional arguments: subnav.
|
||||||
|
{
|
||||||
|
'id': 'myFiles',
|
||||||
|
'alias': 'My Files',
|
||||||
|
'fa': 'home'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
*/
|
||||||
|
|
||||||
|
function get(name) {
|
||||||
|
ele = document.querySelectorAll(name)
|
||||||
|
return (ele.length === 1) ? ele[0] : ele;
|
||||||
|
};
|
||||||
|
|
||||||
|
function element(type, dict) {
|
||||||
|
ele = document.createElement(type);
|
||||||
|
for(var [k,v] of Object.entries(dict)) {
|
||||||
|
if(k === 'text') {
|
||||||
|
ele.appendChild(document.createTextNode(v));
|
||||||
|
} else if(k === 'onclick') {
|
||||||
|
ele.onclick = v;
|
||||||
|
} else {
|
||||||
|
ele.setAttribute(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ele;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getDrives() {
|
||||||
|
$.get('./mydrives').done(function(d) {
|
||||||
|
navSelect = d['owned'][0]['_id'] // ADD DEFAULT LATER
|
||||||
|
types = ['owned', 'shared']
|
||||||
|
for(var i = 0; i < types.length; i++) {
|
||||||
|
for(var j = 0; j < d[types[i]].length; j++) {
|
||||||
|
item = {
|
||||||
|
'id': d[types[i]][j]['_id'],
|
||||||
|
'alias': d[types[i]][j]['name'],
|
||||||
|
'fa': 'home',
|
||||||
|
'onclick': function() {
|
||||||
|
if(this.id === navSelect) return;
|
||||||
|
updateNav(this.id);
|
||||||
|
sidebar = get('.closeable');
|
||||||
|
if(sidebar) moveSidebar('close');
|
||||||
|
currDir = '';
|
||||||
|
listDir(currDir, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drives[item['id']] = item['alias'];
|
||||||
|
navi[types[i]].push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
navLayout();
|
||||||
|
updateNav(navSelect);
|
||||||
|
listDir(currDir, 0);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Directory is the sub-directory, sec is the section of data,
|
||||||
|
// if files need to be split up into sections.
|
||||||
|
|
||||||
|
function listDir(dir, sec) {
|
||||||
|
$.post('./files', {'drive_id': navSelect, 'path': currDir})
|
||||||
|
.done(function(d) {
|
||||||
|
data = [[],[]];
|
||||||
|
for(var i = 0; i < d.length; i++) {
|
||||||
|
if(d[i]['folder']) {
|
||||||
|
data[0].push(d[i]);
|
||||||
|
} else {
|
||||||
|
d[i].date = Date.parse(d[i].date);
|
||||||
|
data[1].push(d[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sortFiles('name', -1);
|
||||||
|
clickable = true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function downloadFile(path) {
|
||||||
|
alertBox('Downloading file...', 'msg');
|
||||||
|
$.post('./files', {'drive_id': navSelect, 'path': path}).done(function(d) {
|
||||||
|
window.location = './d/' + d;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function sortSection(type, direc, arr) {
|
||||||
|
var sorted = arr;
|
||||||
|
switch(type) {
|
||||||
|
case 'name':
|
||||||
|
sorted.sort(function(a, b) {
|
||||||
|
return (a.name < b.name) ? direc*1 : direc*-1;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'date':
|
||||||
|
sorted.sort(function(a, b){
|
||||||
|
return (a.date < b.date) ? direc*1 : direc*-1;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'size':
|
||||||
|
sorted.sort(function(a, b) {
|
||||||
|
return (a['real_size'] < b['real_size']) ? direc*1 : direc*-1;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return sorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
function navLayout() {
|
||||||
|
function createNavHeader(text) {
|
||||||
|
get('#sidebarItems').appendChild(element('div', {
|
||||||
|
class: 'naviHead transition',
|
||||||
|
text: text
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
function createNav(navi) { // Create navigation tabs on sidebar.
|
||||||
|
var side = get('#sidebarItems');
|
||||||
|
navi.forEach(function(ele) {
|
||||||
|
var div = element('div', {
|
||||||
|
id: ele.id,
|
||||||
|
class: 'navi transition',
|
||||||
|
onclick: ele.onclick
|
||||||
|
});
|
||||||
|
|
||||||
|
div.appendChild(element('i', {
|
||||||
|
class: `fa fa-${ele.fa}`
|
||||||
|
}));
|
||||||
|
|
||||||
|
div.appendChild(element('p', {
|
||||||
|
text: ele.alias
|
||||||
|
}))
|
||||||
|
|
||||||
|
side.appendChild(div);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
createNavHeader('My Drives');
|
||||||
|
createNav(navi['owned']);
|
||||||
|
createNavHeader('Shared Drives');
|
||||||
|
createNav(navi['shared']);
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateNav(op) { // Updates the sidebar navigation.
|
||||||
|
var oldNav = document.getElementById(navSelect);
|
||||||
|
var newNav = document.getElementById(op);
|
||||||
|
navSelect = op;
|
||||||
|
oldNav.style.backgroundColor = 'rgba(0,0,0,0)';
|
||||||
|
oldNav.style.color = 'white';
|
||||||
|
newNav.style.backgroundColor = themeColors.main;
|
||||||
|
newNav.style.color = themeColors.highlight;
|
||||||
|
};
|
||||||
|
|
||||||
|
function clearTbl() {
|
||||||
|
selectDiv = undefined;
|
||||||
|
get('#directoryCont').style.opacity = '0';
|
||||||
|
};
|
||||||
|
|
||||||
|
function animFade(type, div) {
|
||||||
|
if(type === 'open') {
|
||||||
|
div.style.display = 'block';
|
||||||
|
setTimeout(function() {
|
||||||
|
div.style.opacity = '1';
|
||||||
|
}, 10);
|
||||||
|
} else if(type === 'close') {
|
||||||
|
div.style.opacity = '0';
|
||||||
|
setTimeout(function() {
|
||||||
|
div.style.display = 'none';
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function dateStr(date, type) {
|
||||||
|
type = type || 'all';
|
||||||
|
var str = new Date(date).toLocaleString();
|
||||||
|
if(type === 'all') {
|
||||||
|
return str.replace(',', ' | ');
|
||||||
|
} else if(type === 'date') {
|
||||||
|
return str.substring(0, str.indexOf(','));
|
||||||
|
} else if(Type === 'time') {
|
||||||
|
return str.substring(str.indexOf(',') + 1, str.length);
|
||||||
|
}
|
||||||
|
};
|
||||||
91
main.php
91
main.php
@ -1,91 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if(isset($_POST['getdir']) && !empty($_POST['getdir'])) {
|
|
||||||
$dir = $_POST['getdir'];
|
|
||||||
echo json_encode((listDir($dir[0],$dir[1])));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($_POST['rootdir']) && !empty($_POST['rootdir'])) {
|
|
||||||
echo json_encode('/Database'.'/');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($_POST['zip']) && !empty($_POST['zip'])) {
|
|
||||||
$info = $_POST['zip'];
|
|
||||||
zip($info[0],$info[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function listDir($relroot,$section) {
|
|
||||||
$folder = getcwd().$relroot;
|
|
||||||
$paths = scandir($folder);
|
|
||||||
$ext = array("ext");
|
|
||||||
$mod = array("mod");
|
|
||||||
$size = array("size");
|
|
||||||
|
|
||||||
$paths = array_slice($paths,$section*100,100);
|
|
||||||
|
|
||||||
foreach ($paths as $dir) {
|
|
||||||
$realdir = $folder.'/'.$dir;
|
|
||||||
if(is_dir($realdir)) {
|
|
||||||
$ext[] = 'true';
|
|
||||||
$size[] = "- - - -";
|
|
||||||
} else {
|
|
||||||
$ext[] = 'false';
|
|
||||||
$size[] = human_filesize(filesize($realdir));
|
|
||||||
}
|
|
||||||
$mod[] = date ("F d, Y | H:i:s", filemtime($realdir));
|
|
||||||
}
|
|
||||||
|
|
||||||
$results[] = $paths;
|
|
||||||
$results[] = $ext;
|
|
||||||
$results[] = $mod;
|
|
||||||
$results[] = $size;
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
|
|
||||||
function human_filesize($bytes, $decimals = 2) {
|
|
||||||
$sz = 'BKMGTP';
|
|
||||||
$factor = floor((strlen($bytes) - 1) / 3);
|
|
||||||
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor].'B';
|
|
||||||
}
|
|
||||||
|
|
||||||
function zip($path,$title) {
|
|
||||||
$root = getcwd();
|
|
||||||
// Get real path for our folder
|
|
||||||
$rootPath = $root.$path;
|
|
||||||
|
|
||||||
// Initialize archive object
|
|
||||||
|
|
||||||
$zip = new ZipArchive();
|
|
||||||
|
|
||||||
$ziploc = $root.'/zip'.'/'.$title;
|
|
||||||
$zip->open($ziploc, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
|
||||||
|
|
||||||
// Create recursive directory iterator
|
|
||||||
/* @var SplFileInfo[] $files */
|
|
||||||
$files = new RecursiveIteratorIterator(
|
|
||||||
new RecursiveDirectoryIterator($rootPath),
|
|
||||||
RecursiveIteratorIterator::LEAVES_ONLY
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($files as $name => $file)
|
|
||||||
{
|
|
||||||
// Skip directories (they would be added automatically)
|
|
||||||
if (!$file->isDir())
|
|
||||||
{
|
|
||||||
// Get real and relative path for current file
|
|
||||||
$filePath = $file->getRealPath();
|
|
||||||
$relativePath = substr($filePath, strlen($rootPath) + 1);
|
|
||||||
|
|
||||||
// Add current file to archive
|
|
||||||
$zip->addFile($filePath, $relativePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zip archive will be created only after closing object
|
|
||||||
$zip->close();
|
|
||||||
|
|
||||||
return '/zip'.'/'.$title;
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
<body>
|
|
||||||
<div id="header">
|
|
||||||
<div class="transition">
|
|
||||||
<i class="fa fa-bars transition"></i>
|
|
||||||
</div>
|
|
||||||
<h1>BinBin</h1>
|
|
||||||
<div class="transition">
|
|
||||||
<i class="fa fa-ellipsis-v"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="directoryHeader">
|
|
||||||
<p id="location" class="transition">BinBin</p>
|
|
||||||
<p class="transition">Name</p>
|
|
||||||
<i class="fa fa-arrow-up transition"></i>
|
|
||||||
</div>
|
|
||||||
<div id="sidebar" class="transition">
|
|
||||||
<span>Developed by <p onclick="window.open('https://github.com/ksjdragon/binbin.git','_blank')">ksjdragon</p></span>
|
|
||||||
</div>
|
|
||||||
<div id="mainContainer">
|
|
||||||
<div id="directory">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="dotMenu" class="card">
|
|
||||||
<p id="openSort" class="transition">Sort by...</p>
|
|
||||||
<a id="download" class="transition" download>Download</a>
|
|
||||||
</div>
|
|
||||||
<div id="menuOverlay" class="transition">
|
|
||||||
<div id="optionContainer" class="transition">
|
|
||||||
<p>Sort by</p>
|
|
||||||
<p>Name</p>
|
|
||||||
<p>Date</p>
|
|
||||||
<p>Size</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<input id="copy" readonly>
|
|
||||||
</body>
|
|
||||||
606
mobile/mobile.js
606
mobile/mobile.js
@ -1,606 +0,0 @@
|
|||||||
var data, // Stores data from PHP.
|
|
||||||
section = 0,
|
|
||||||
clickable = true,
|
|
||||||
selectName, // Stores name of folder in selected div
|
|
||||||
selectDiv, // Stores actual selected div.
|
|
||||||
currDir = "";
|
|
||||||
|
|
||||||
var sort = {
|
|
||||||
"name": -1,
|
|
||||||
"date": 1,
|
|
||||||
"size": 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
var faIcons = {
|
|
||||||
"fol": "folder",
|
|
||||||
"mp3": "music",
|
|
||||||
"wav": "music",
|
|
||||||
"ogg": "music",
|
|
||||||
"mp4": "video-camera",
|
|
||||||
"zip": "file-zip-o",
|
|
||||||
"other": "file-o"
|
|
||||||
};
|
|
||||||
|
|
||||||
var navi = [ // Necessary arguments: id, alias, fa | Optional arguments: subnav.
|
|
||||||
{
|
|
||||||
"id": "myFiles",
|
|
||||||
"alias": "My Files",
|
|
||||||
"fa": "home"
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
var navSelect = "myFiles";
|
|
||||||
|
|
||||||
var themeColors = { // For reference and for quick changing if need-be.
|
|
||||||
"main": "#3e505a",
|
|
||||||
"sidebar": "#2a2e31",
|
|
||||||
"highlight": "#fff"
|
|
||||||
};
|
|
||||||
|
|
||||||
function getData() {
|
|
||||||
$.when($.ajax({
|
|
||||||
type : 'POST',
|
|
||||||
url: 'main.php',
|
|
||||||
data: {rootdir: 'rootdir'}
|
|
||||||
})).done(function(d) {
|
|
||||||
rootDir = JSON.parse(d);
|
|
||||||
checkHash();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function listDir(dir, sec) { // Directory is the sub-directory, sec is the section of data, if files need to be split up into sections.
|
|
||||||
var real = rootDir+dir;
|
|
||||||
$.when($.ajax({
|
|
||||||
type : 'POST',
|
|
||||||
url: 'main.php',
|
|
||||||
data: {getdir : [real, sec]},
|
|
||||||
})).done(function(d) {
|
|
||||||
data = JSON.parse(d);
|
|
||||||
if(data[0] === null) {
|
|
||||||
currDir = "";
|
|
||||||
listDir(currDir, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(sec == 0) {
|
|
||||||
data[0].splice(0,2);
|
|
||||||
data[1].splice(0,3);
|
|
||||||
data[2].splice(0,3);
|
|
||||||
data[3].splice(0,3);
|
|
||||||
} else {
|
|
||||||
data[1].splice(0,1);
|
|
||||||
data[2].splice(0,1);
|
|
||||||
data[3].splice(0,1);
|
|
||||||
}
|
|
||||||
var toObj = [];
|
|
||||||
for(var i = 0; i < data[0].length; i++) {
|
|
||||||
toObj.push({
|
|
||||||
name: data[0][i],
|
|
||||||
folder: data[1][i],
|
|
||||||
date: data[2][i],
|
|
||||||
size: data[3][i]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
data = toObj;
|
|
||||||
sortFiles("name", -1);
|
|
||||||
clickable = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortFiles(type, direction) {
|
|
||||||
switch(type) {
|
|
||||||
case "name":
|
|
||||||
data.sort(function(a, b){ return (a.name < b.name) ? direction*1 : direction*-1;});
|
|
||||||
break;
|
|
||||||
case "date":
|
|
||||||
data.sort(function(a, b){
|
|
||||||
a = a.date.replace(",","").split(" ");
|
|
||||||
b = b.date.replace(",","").split(" ");
|
|
||||||
a = Date.parse(a[1] + " " + a[0] + " " + a[2]);
|
|
||||||
b = Date.parse(b[1] + " " + b[0] + " " + b[2]);
|
|
||||||
|
|
||||||
return (a < b) ? direction*1 : direction*-1;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "size":
|
|
||||||
data.sort(function(a, b){ return (a.size.replace("B","").substring(0, a.size.length-1) < b.size.replace("B","").substring(0, b.size.length-1)) ? direction*1 : direction*-1;});
|
|
||||||
}
|
|
||||||
var p = document.querySelectorAll("#directoryHeader p:nth-child(2)")[0];
|
|
||||||
var i = document.querySelectorAll("#directoryHeader i")[0];
|
|
||||||
p.style.opacity = "0";
|
|
||||||
i.style.opacity = "0";
|
|
||||||
setTimeout(function() {
|
|
||||||
p.innerText = type[0].toUpperCase() + type.substring(1,type.length);
|
|
||||||
i.className = "fa fa-arrow-" + ((direction < 0) ? "up" : "down") + " transition";
|
|
||||||
p.style.opacity = "1";
|
|
||||||
i.style.opacity = "1";
|
|
||||||
}, 300);
|
|
||||||
|
|
||||||
try {
|
|
||||||
clearTbl();
|
|
||||||
setTimeout(function() {
|
|
||||||
document.getElementById("directory").removeChild(document.getElementById("directoryCont"));
|
|
||||||
dispDir();
|
|
||||||
}, 300);
|
|
||||||
} catch(err) {
|
|
||||||
dispDir();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function dispDir() {
|
|
||||||
updateLocation();
|
|
||||||
try {
|
|
||||||
document.getElementById("directory").removeChild(document.getElementById("directoryCont"));
|
|
||||||
} catch(err) {}
|
|
||||||
var cont = document.createElement("div");
|
|
||||||
cont.id = "directoryCont";
|
|
||||||
cont.style.opacity = "0";
|
|
||||||
cont.className = "transition";
|
|
||||||
|
|
||||||
selectName = "";
|
|
||||||
var item;
|
|
||||||
if(data.length === 0) {
|
|
||||||
var p = document.createElement("p");
|
|
||||||
p.appendChild(document.createTextNode("Nothing here!"));
|
|
||||||
p.style.fontWeight = "100";
|
|
||||||
cont.appendChild(p);
|
|
||||||
}
|
|
||||||
for(var i = 0; i < data.length; i++) {
|
|
||||||
item = createRow();
|
|
||||||
|
|
||||||
var curr = data[i];
|
|
||||||
var name = document.createTextNode(curr.name);
|
|
||||||
var otherInfo = document.createTextNode(curr.date.split(" | ")[0] + " | " + curr.size);
|
|
||||||
|
|
||||||
item.childNodes[0].appendChild(name);
|
|
||||||
item.childNodes[1].appendChild(otherInfo);
|
|
||||||
|
|
||||||
var ext = document.createAttribute("ext");
|
|
||||||
|
|
||||||
if(curr.folder == "true") {
|
|
||||||
ext.value = "fol";
|
|
||||||
} else {
|
|
||||||
ext.value = curr.name.substring(curr.name.lastIndexOf(".")+1,curr.name.length).toLowerCase();
|
|
||||||
url = getURI(curr.name);
|
|
||||||
var f = document.createElement("i");
|
|
||||||
var a = document.createElement("div");
|
|
||||||
a.setAttribute("url", url);
|
|
||||||
f.className = "fa fa-files-o transition";
|
|
||||||
a.appendChild(f);
|
|
||||||
a.onclick = function() {
|
|
||||||
this.style.backgroundColor = "rgba(0,0,0,0.4)";
|
|
||||||
that = this;
|
|
||||||
setTimeout(function() {
|
|
||||||
that.style.backgroundColor = "rgba(0,0,0,0)";
|
|
||||||
}, 300);
|
|
||||||
document.getElementById("copy").value = this.getAttribute("url");
|
|
||||||
document.getElementById("copy").select();
|
|
||||||
document.execCommand("copy");
|
|
||||||
}
|
|
||||||
item.appendChild(a);
|
|
||||||
}
|
|
||||||
item.setAttributeNode(ext);
|
|
||||||
|
|
||||||
var ico = document.createElement("div");
|
|
||||||
ico.className = "fileIcon";
|
|
||||||
var faico = document.createElement("i");
|
|
||||||
faico.className = "fa fa-" + (faIcons[item.getAttribute("ext")] || faIcons["other"]);
|
|
||||||
ico.appendChild(faico);
|
|
||||||
item.appendChild(ico);
|
|
||||||
|
|
||||||
item.onclick = function() {
|
|
||||||
if(clickable == true) {
|
|
||||||
var name = this.childNodes[0].innerText;
|
|
||||||
url = getURI(name);
|
|
||||||
attr = this.getAttribute("ext");
|
|
||||||
var download = document.querySelectorAll("#dotMenu a")[0]
|
|
||||||
if(attr == "fol") {
|
|
||||||
download.href = ""
|
|
||||||
download.style.color = "rgba(0,0,0,0.5)";
|
|
||||||
} else {
|
|
||||||
download.href = url;
|
|
||||||
download.style.color = "rgba(0,0,0,1)";
|
|
||||||
}
|
|
||||||
if(selectName == name) {
|
|
||||||
clickable = false;
|
|
||||||
if(attr == "fol") {
|
|
||||||
clearTbl();
|
|
||||||
setTimeout(function() {
|
|
||||||
currDir += name+"/";
|
|
||||||
listDir(currDir,0);
|
|
||||||
}, 300)
|
|
||||||
return;
|
|
||||||
} else if (attr == "mkv" || attr == "mp4") {
|
|
||||||
videoOverlay(url);
|
|
||||||
} else if (attr == "png" || attr == "jpg" || attr == "gif") {
|
|
||||||
imageOverlay(url);
|
|
||||||
} else if (attr == "mp3" || attr == "ogg") {
|
|
||||||
audioOverlay(url);
|
|
||||||
clickable = true;
|
|
||||||
} else {
|
|
||||||
downloadFile(rootDir + currDir + name, 'n');
|
|
||||||
clickable = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selectName = name;
|
|
||||||
selectDiv = this;
|
|
||||||
for(var i =0; i < document.getElementsByClassName("item").length;i++){
|
|
||||||
document.getElementsByClassName("item")[i].style.backgroundColor = "";
|
|
||||||
}
|
|
||||||
this.style.backgroundColor = "rgba(255,255,255,0.2)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cont.appendChild(item);
|
|
||||||
item = null;
|
|
||||||
}
|
|
||||||
document.getElementById("directory").appendChild(cont);
|
|
||||||
setTimeout(function() {
|
|
||||||
document.getElementById("directoryCont").style.opacity = "1";
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getClose() {
|
|
||||||
var close = document.createElement("i");
|
|
||||||
close.className = "fa fa-times transition";
|
|
||||||
var attr = document.createAttribute("aria-hidden");
|
|
||||||
attr.value = "true";
|
|
||||||
close.setAttributeNode(attr);
|
|
||||||
|
|
||||||
close.onclick = function() {
|
|
||||||
this.style.color = "#f13838";
|
|
||||||
that = this;
|
|
||||||
document.getElementsByClassName("overlay")[0].opacity = "0";
|
|
||||||
setTimeout(function() {
|
|
||||||
that.style.color = "white";
|
|
||||||
document.getElementsByTagName("body")[0].removeChild(document.getElementsByClassName("overlay")[0]);
|
|
||||||
clickable = true;
|
|
||||||
}, 300);
|
|
||||||
};
|
|
||||||
|
|
||||||
return close;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createRow() {
|
|
||||||
var item = document.createElement("div");
|
|
||||||
item.className = "item transition";
|
|
||||||
var name = document.createElement("p");
|
|
||||||
name.className = "name";
|
|
||||||
item.appendChild(name);
|
|
||||||
var modified = document.createElement("p");
|
|
||||||
modified.className = "modified";
|
|
||||||
item.appendChild(modified);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
function videoOverlay(url) {
|
|
||||||
var overlay = getDefaultOverlay();
|
|
||||||
|
|
||||||
var video = document.createElement("video");
|
|
||||||
video.onclick = function() {event.stopPropagation();}
|
|
||||||
video.src = url;
|
|
||||||
video.controls = true;
|
|
||||||
video.autoplay = true;
|
|
||||||
video.type = "video/mp4";
|
|
||||||
|
|
||||||
video.style.margin = "auto";
|
|
||||||
video.style.backgroundColor = "black";
|
|
||||||
|
|
||||||
video.onloadedmetadata = function() {
|
|
||||||
if((video.videoHeight/video.videoWidth) > (window.innerHeight/window.innerWidth)) {
|
|
||||||
video.style.height = (window.innerHeight * 0.9).toString() + "px";
|
|
||||||
} else {
|
|
||||||
video.style.width = (window.innerWidth * 0.9).toString() + "px";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var div = document.createElement("div");
|
|
||||||
div.style.margin = "auto";
|
|
||||||
div.style.gridRow = "1";
|
|
||||||
div.style.gridColumn = "1";
|
|
||||||
div.appendChild(video);
|
|
||||||
overlay.appendChild(div);
|
|
||||||
|
|
||||||
var close = getClose();
|
|
||||||
overlay.appendChild(close);
|
|
||||||
|
|
||||||
document.getElementsByTagName("body")[0].appendChild(overlay);
|
|
||||||
setTimeout(function() {
|
|
||||||
overlay.style.opacity = "1";
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function audioOverlay(url) {
|
|
||||||
var overlay = getDefaultOverlay();
|
|
||||||
var audio = document.createElement("audio");
|
|
||||||
audio.onclick = function() {event.stopPropagation();}
|
|
||||||
audio.src = url;
|
|
||||||
audio.controls = true;
|
|
||||||
audio.autoplay = true;
|
|
||||||
|
|
||||||
audio.style.margin = "auto";
|
|
||||||
audio.style.width = (window.innerWidth * 0.9).toString() + "px";
|
|
||||||
|
|
||||||
var div = document.createElement("div");
|
|
||||||
div.style.margin = "auto";
|
|
||||||
div.style.gridRow = "1";
|
|
||||||
div.style.gridColumn = "1";
|
|
||||||
div.appendChild(audio);
|
|
||||||
overlay.appendChild(div);
|
|
||||||
|
|
||||||
var close = getClose();
|
|
||||||
overlay.appendChild(close);
|
|
||||||
|
|
||||||
document.getElementsByTagName("body")[0].appendChild(overlay);
|
|
||||||
setTimeout(function() {
|
|
||||||
overlay.style.opacity = "1";
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function imageOverlay(url) {
|
|
||||||
var overlay = getDefaultOverlay();
|
|
||||||
var img = new Image();
|
|
||||||
img.src = url;
|
|
||||||
img.style.margin = "auto";
|
|
||||||
|
|
||||||
var image = document.createElement("img");
|
|
||||||
image.src = url;
|
|
||||||
img.onload = function() {
|
|
||||||
var height = img.height;
|
|
||||||
var width = img.width;
|
|
||||||
|
|
||||||
|
|
||||||
if((height/width) > (window.innerHeight/window.innerWidth)) {
|
|
||||||
image.style.height = (window.innerHeight * 0.9).toString() + "px";
|
|
||||||
} else {
|
|
||||||
image.style.width = (window.innerWidth * 0.9).toString() + "px";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var div = document.createElement("div");
|
|
||||||
div.style.margin = "auto";
|
|
||||||
div.style.gridRow = "1";
|
|
||||||
div.style.gridColumn = "1";
|
|
||||||
div.appendChild(image);
|
|
||||||
overlay.appendChild(div);
|
|
||||||
|
|
||||||
var close = getClose();
|
|
||||||
overlay.appendChild(close);
|
|
||||||
|
|
||||||
document.getElementsByTagName("body")[0].appendChild(overlay);
|
|
||||||
setTimeout(function() {
|
|
||||||
overlay.style.opacity = "1";
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDefaultOverlay() {
|
|
||||||
var overlay = document.createElement("div");
|
|
||||||
overlay.className = "overlay transition";
|
|
||||||
overlay.style.position = "absolute";
|
|
||||||
overlay.style.top = "0";
|
|
||||||
overlay.style.left = "0";
|
|
||||||
overlay.style.minHeight = "100%";
|
|
||||||
overlay.style.minWidth = "100%";
|
|
||||||
overlay.style.background = 'rgba(0,0,0,0.8)';
|
|
||||||
overlay.style.zIndex = "50";
|
|
||||||
overlay.style.display = "grid";
|
|
||||||
overlay.style.gridTemplateColumns = "1fr";
|
|
||||||
overlay.style.gridTemplateRows = "1fr";
|
|
||||||
overlay.style.opacity = "0";
|
|
||||||
|
|
||||||
return overlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearTbl() {
|
|
||||||
selected = undefined;
|
|
||||||
selectDiv = undefined;
|
|
||||||
document.getElementById("directoryCont").style.opacity = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getURI(name) {
|
|
||||||
var dirs = (rootDir+currDir+name).split("/");
|
|
||||||
var uri = window.location.origin;
|
|
||||||
for(var i = 1; i < dirs.length; i++) uri+="/"+encodeURIComponent(dirs[i]);
|
|
||||||
return uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createNav() {
|
|
||||||
for (var i = 0; i < navi.length; i++) { // Create navigation tabs.
|
|
||||||
var side = document.getElementById("sidebar");
|
|
||||||
var div = document.createElement("div");
|
|
||||||
div.className = "navi transition";
|
|
||||||
div.setAttribute("option", navi[i].id);
|
|
||||||
var ic = document.createElement("i");
|
|
||||||
ic.className = "fa fa-" + navi[i].fa;
|
|
||||||
ic["aria-hidden"] = true;
|
|
||||||
var p = document.createElement("p");
|
|
||||||
p.appendChild(document.createTextNode(navi[i].alias));
|
|
||||||
div.appendChild(ic);
|
|
||||||
div.appendChild(p);
|
|
||||||
side.appendChild(div);
|
|
||||||
var subNav = navi[i].subNav;
|
|
||||||
if(!subNav) continue;
|
|
||||||
|
|
||||||
var subNavCont = document.createElement("div");
|
|
||||||
subNavCont.className = "naviInner";
|
|
||||||
subNavCont.setAttribute("option", navi[i].id);
|
|
||||||
for(var j = 0; j < subNav.length; j++) {
|
|
||||||
var eachSubNav = document.createElement("div");
|
|
||||||
eachSubNav.className = "transition";
|
|
||||||
eachSubNav.setAttribute("option", navi[i].id+"&"+subNav[j].id);
|
|
||||||
eachSubNav.onclick = function() {
|
|
||||||
var op = this.getAttribute("option");
|
|
||||||
if(subNavSelect === op) return;
|
|
||||||
//updateMain(op);
|
|
||||||
}
|
|
||||||
var p2 = document.createElement("p");
|
|
||||||
p2.appendChild(document.createTextNode(subNav[j].alias));
|
|
||||||
eachSubNav.appendChild(p2);
|
|
||||||
subNavCont.appendChild(eachSubNav);
|
|
||||||
}
|
|
||||||
side.appendChild(subNavCont);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateNav(op) { // Updates the sidebar navigation (if naviagation tabs are ever dynamically implemented).
|
|
||||||
var oldNav = document.querySelectorAll("[option=" + navSelect + "]")[0];
|
|
||||||
var newNav = document.querySelectorAll("[option=" + op + "]")[0];
|
|
||||||
oldNav.style.backgroundColor = "rgba(0,0,0,0)";
|
|
||||||
oldNav.style.color = "white";
|
|
||||||
newNav.style.backgroundColor = themeColors.main;
|
|
||||||
newNav.style.color = themeColors.highlight;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateLocation() {
|
|
||||||
window.location.hash = currDir.replace(/[\/]+/g,"*").replace(/ /g, "_");
|
|
||||||
var i = document.querySelectorAll("#header div:first-child i")[0];
|
|
||||||
document.getElementById("location").innerText = (currDir === "") ? "BinBin" : currDir.split("/").slice(-2)[0];
|
|
||||||
if(currDir === "" && !i.className.includes("fa-bars")) {
|
|
||||||
i.style.opacity = "0";
|
|
||||||
setTimeout(function() {
|
|
||||||
i.className = "fa fa-bars transition";
|
|
||||||
i.style.opacity = "1"
|
|
||||||
}, 300);
|
|
||||||
} else if(currDir !== "" && !i.className.includes("fa-arrow-left")) {
|
|
||||||
i.style.opacity = "0";
|
|
||||||
setTimeout(function() {
|
|
||||||
i.className = "fa fa-arrow-left transition";
|
|
||||||
i.style.opacity = "1";
|
|
||||||
}, 300);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkHash() {
|
|
||||||
if(window.location.hash) {
|
|
||||||
currDir = window.location.hash.replace(/[_]+/g, " ").replace(/[\*]+/g,"/").replace("#","");
|
|
||||||
}
|
|
||||||
listDir(currDir,0);
|
|
||||||
window.location.hash = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeMenuOverlay() {
|
|
||||||
var overlay = document.getElementById("menuOverlay");
|
|
||||||
overlay.style.opacity = "0";
|
|
||||||
setTimeout(function() {
|
|
||||||
overlay.style.display = "none";
|
|
||||||
}, 300);
|
|
||||||
document.getElementById("optionContainer").style.bottom = "-60%";
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortButtons() {
|
|
||||||
document.querySelectorAll("#optionContainer p:first-child")[0].onclick = function() {event.stopPropagation();}
|
|
||||||
document.querySelectorAll("#optionContainer p:nth-child(2)")[0].onclick = function() {
|
|
||||||
event.stopPropagation();
|
|
||||||
closeMenuOverlay();
|
|
||||||
sort.name = sort.name * -1;
|
|
||||||
sortFiles("name", sort.name);
|
|
||||||
}
|
|
||||||
document.querySelectorAll("#optionContainer p:nth-child(3)")[0].onclick = function() {
|
|
||||||
event.stopPropagation();
|
|
||||||
closeMenuOverlay();
|
|
||||||
sort.date = sort.date * -1;
|
|
||||||
sortFiles("date", sort.date);
|
|
||||||
}
|
|
||||||
document.querySelectorAll("#optionContainer p:nth-child(4)")[0].onclick = function() {
|
|
||||||
event.stopPropagation();
|
|
||||||
closeMenuOverlay();
|
|
||||||
sort.size = sort.size * -1;
|
|
||||||
sortFiles("size", sort.size);
|
|
||||||
}
|
|
||||||
document.querySelectorAll("#directoryHeader p:nth-child(2)")[0].onclick = function() {
|
|
||||||
var type = this.innerText.toLowerCase();
|
|
||||||
sort[type] = sort[type] * -1;
|
|
||||||
sortFiles(type, sort[type]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelectorAll("#header div:first-child i")[0].onclick = function() {
|
|
||||||
this.parentNode.style.backgroundColor = "rgba(0,0,0,0.4)";
|
|
||||||
that = this;
|
|
||||||
setTimeout(function() {
|
|
||||||
that.parentNode.style.backgroundColor = "rgba(0,0,0,0)";
|
|
||||||
}, 300);
|
|
||||||
if(currDir === "") {
|
|
||||||
setTimeout(function() {
|
|
||||||
document.getElementById("sidebar").style.left = "0";
|
|
||||||
}, 10);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
var arr = currDir.split("/");
|
|
||||||
if(arr.length === 2) {
|
|
||||||
currDir = "";
|
|
||||||
} else {
|
|
||||||
currDir = arr.slice(0,arr.length-2).reduce((a,b) => a+"/"+b)+"/";
|
|
||||||
}
|
|
||||||
listDir(currDir, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("sidebar").onclick = function() {
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.querySelectorAll("#header div:last-child i")[0].onclick = function(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
this.parentNode.style.backgroundColor = "rgba(0,0,0,0.4)";
|
|
||||||
that = this;
|
|
||||||
setTimeout(function() {
|
|
||||||
that.parentNode.style.backgroundColor = "rgba(0,0,0,0)";
|
|
||||||
}, 300);
|
|
||||||
var menu = document.getElementById("dotMenu");
|
|
||||||
menu.style.display = "block";
|
|
||||||
setTimeout(function() {
|
|
||||||
menu.style.opacity = "1";
|
|
||||||
}, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("openSort").onclick = function() {
|
|
||||||
event.stopPropagation();
|
|
||||||
this.style.backgroundColor = "rgba(0,0,0,0.2)";
|
|
||||||
that = this;
|
|
||||||
setTimeout(function() {
|
|
||||||
that.style.backgroundColor = "rgba(0,0,0,0)";
|
|
||||||
}, 300);
|
|
||||||
// Close Menu
|
|
||||||
var menu = document.getElementById("dotMenu");
|
|
||||||
menu.style.opacity = "0";
|
|
||||||
setTimeout(function() {
|
|
||||||
menu.style.display = "none";
|
|
||||||
}, 300);
|
|
||||||
// Open overlay
|
|
||||||
var overlay = document.getElementById("menuOverlay");
|
|
||||||
overlay.style.display = "block";
|
|
||||||
setTimeout(function() {
|
|
||||||
overlay.style.opacity = "1";
|
|
||||||
}, 10);
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
var option = document.getElementById("optionContainer");
|
|
||||||
option.style.bottom = "0";
|
|
||||||
}, 150);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("download").onclick = function() {
|
|
||||||
event.stopPropagation();
|
|
||||||
this.style.backgroundColor = "rgba(0,0,0,0.2)";
|
|
||||||
that = this;
|
|
||||||
setTimeout(function() {
|
|
||||||
that.style.backgroundColor = "rgba(0,0,0,0)";
|
|
||||||
}, 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.onclick = function(event) {
|
|
||||||
var menu = document.getElementById("dotMenu");
|
|
||||||
menu.style.opacity = "0";
|
|
||||||
setTimeout(function() {
|
|
||||||
menu.style.display = "none";
|
|
||||||
}, 300);
|
|
||||||
|
|
||||||
closeMenuOverlay();
|
|
||||||
|
|
||||||
document.getElementById("sidebar").style.left = "-80%";
|
|
||||||
}
|
|
||||||
|
|
||||||
getData();
|
|
||||||
sortButtons();
|
|
||||||
createNav();
|
|
||||||
updateNav(navSelect);
|
|
||||||
125
templates/404.html
Normal file
125
templates/404.html
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||||
|
<title>BinBin</title>
|
||||||
|
<link rel="icon" href="./assets/favicon.ico?v=2">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab:700" rel="stylesheet">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
min-height: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'Roboto Slab', sans-serif;
|
||||||
|
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: grid;
|
||||||
|
background-color: #0e0e0e;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: auto;
|
||||||
|
font-family: 'Roboto Slab', sans-serif;
|
||||||
|
font-size: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#front {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
background: rgba(0,0,0,0.85);
|
||||||
|
line-height: 100vh;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 5;
|
||||||
|
color: #fff;
|
||||||
|
mix-blend-mode: overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
mix-blend-mode: screen;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas" width=window.innerHeight></canvas>
|
||||||
|
<h1 id='front'>404</h1>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script src="./js/tools.js"></script>
|
||||||
|
<script>
|
||||||
|
var t = 0;
|
||||||
|
|
||||||
|
function drawCanvas() {
|
||||||
|
var el = get("canvas")
|
||||||
|
var c = el.getContext("2d")
|
||||||
|
var block = 10, space = 2, size = block+space;
|
||||||
|
var period = 100, freq = 2*Math.PI/period, step = 1.4, base = 0.05;
|
||||||
|
|
||||||
|
var col = randColor();
|
||||||
|
var dir = randDir();
|
||||||
|
|
||||||
|
function animCanvas(t, col) {
|
||||||
|
// To update when window changes.
|
||||||
|
var w = window.innerWidth, h = window.innerHeight;
|
||||||
|
var x = w/size, y = h/size;
|
||||||
|
var offX = -(w-Math.floor(x)*size)/2, offY = -(h-Math.floor(y)*size)/2;
|
||||||
|
|
||||||
|
el.width = w, el.height = h;
|
||||||
|
|
||||||
|
c.fillStyle = "#0e0e0e";
|
||||||
|
c.fillRect(0, 0, w, h);
|
||||||
|
for(var i = 0; i < x+1; i++) {
|
||||||
|
for(var j = 0; j < y+1; j++) {
|
||||||
|
var intes = Math.round(step*Math.cos((i+j*dir[0]+t*dir[1])*freq)+step)*0.2/step+base
|
||||||
|
c.fillStyle = `rgba(${col[0]},${col[1]},${col[2]},${intes})`;
|
||||||
|
c.fillRect(i*size+offX, j*size+offY, block, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function randColor() {
|
||||||
|
var arr = [
|
||||||
|
128*Math.round(2*Math.random())-1,
|
||||||
|
128*Math.round(2*Math.random())-1,
|
||||||
|
128*Math.round(2*Math.random())-1
|
||||||
|
];
|
||||||
|
while(arr[0]+arr[1]+arr[2] < 382) arr = randColor();
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function randDir() {
|
||||||
|
return [
|
||||||
|
(Math.round(Math.random())) ? -1 : 1,
|
||||||
|
(Math.round(Math.random())) ? -1 : 1
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
setInterval(function() {
|
||||||
|
t += animCanvas(t, col);
|
||||||
|
if(t == period) {
|
||||||
|
t = 0;
|
||||||
|
newCol = randColor();
|
||||||
|
while(newCol === col) newCol == randColor();
|
||||||
|
col = newCol;
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawCanvas();
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
41
templates/desktop.html
Normal file
41
templates/desktop.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<div id="sidebar">
|
||||||
|
<div id="header1" class="transition">
|
||||||
|
<h1>BinBin</h1>
|
||||||
|
</div>
|
||||||
|
<div id="sidebarItems"></div>
|
||||||
|
<span>Developed by <p onclick="window.open('https://github.com/ksjdragon/binbin.git','_blank')">ksjdragon</p></span>
|
||||||
|
</div>
|
||||||
|
<div id="mainContainer">
|
||||||
|
<div id="header2">
|
||||||
|
<div id="topNav">
|
||||||
|
<div id="logout" class="transition" onclick="window.location='./logout';">Logout</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="directory">
|
||||||
|
<div id="directoryLocation" class="transition">
|
||||||
|
<p>a</p>
|
||||||
|
</div>
|
||||||
|
<div id="directoryHeader">
|
||||||
|
<p class="name transition">
|
||||||
|
<span>Name</span>
|
||||||
|
<i class="fa fa-chevron-down transition"></i>
|
||||||
|
<i class="fa fa-chevron-up transition"></i>
|
||||||
|
</p>
|
||||||
|
<p class="date transition">
|
||||||
|
<span>Date Modified</span>
|
||||||
|
<i class="fa fa-chevron-down transition"></i>
|
||||||
|
<i class="fa fa-chevron-up transition"></i>
|
||||||
|
</p>
|
||||||
|
<p class="size transition">
|
||||||
|
<span>Size</span>
|
||||||
|
<i class="fa fa-chevron-down transition"></i>
|
||||||
|
<i class="fa fa-chevron-up transition"></i>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="directoryCont">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<canvas id="visualize" width="1200" height="250"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input id="copy" readonly>
|
||||||
21
templates/drive.html
Normal file
21
templates/drive.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||||
|
<title>BinBin</title>
|
||||||
|
<link rel="icon" href="./assets/favicon.ico?v=2">
|
||||||
|
<link rel="stylesheet" href="./css/drive.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Saira+Condensed:300,400" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab:100,300" rel="stylesheet">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||||
|
<script src="https://use.fontawesome.com/c8d5486cd8.js"></script>
|
||||||
|
<script src="./js/tools.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
35
templates/index.html
Normal file
35
templates/index.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||||
|
<title>BinBin</title>
|
||||||
|
<link rel="icon" href="./assets/favicon.ico?v=2">
|
||||||
|
<link rel="stylesheet" href="./css/index.css">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Saira+Condensed:300,400" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab:100,300" rel="stylesheet">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||||
|
<script src="https://use.fontawesome.com/c8d5486cd8.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<canvas id="canvas" width=window.innerHeight></canvas>
|
||||||
|
<div id="formContainer">
|
||||||
|
<div id="formSizeWrapper">
|
||||||
|
<h1>BinBin</h1>
|
||||||
|
<form id="login" onsubmit="login(form);">
|
||||||
|
<p>Username:</p>
|
||||||
|
<input class="transition" type="text" name="username">
|
||||||
|
<p>Password:</p>
|
||||||
|
<input class="transition" type="password" name="password">
|
||||||
|
</form>
|
||||||
|
<div>
|
||||||
|
<button class="transition" onclick="login(get('#login'));" >Login</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script src="./js/tools.js"></script>
|
||||||
|
<script src="./js/alert.js"></script>
|
||||||
|
<script src="./js/index.js"></script>
|
||||||
|
</html>
|
||||||
35
templates/mobile.html
Normal file
35
templates/mobile.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<div id="header">
|
||||||
|
<div id="barOpen" class="transition">
|
||||||
|
<i class="fa fa-bars transition"></i>
|
||||||
|
</div>
|
||||||
|
<h1>BinBin</h1>
|
||||||
|
<div id="dotOpen" class="transition">
|
||||||
|
<i class="fa fa-ellipsis-v"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="directoryHeader">
|
||||||
|
<p id="location" class="transition"></p>
|
||||||
|
<p id="sortType" class="transition">Name</p>
|
||||||
|
<i id="sortDirection" class="fa fa-arrow-up transition"></i>
|
||||||
|
</div>
|
||||||
|
<div id="sidebar" class="transition closeable">
|
||||||
|
<div id="sidebarItems"></div>
|
||||||
|
<span>Developed by <p onclick="window.open('https://github.com/ksjdragon/binbin.git','_blank')">ksjdragon</p></span>
|
||||||
|
</div>
|
||||||
|
<div id="mainContainer">
|
||||||
|
<div id="directory">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="dotMenu" class="card">
|
||||||
|
<p id="openSort" class="transition">Sort by...</p>
|
||||||
|
<a id="download" class="transition" download>Download</a>
|
||||||
|
</div>
|
||||||
|
<div id="menuOverlay" class="transition">
|
||||||
|
<div id="optionContainer" class="transition">
|
||||||
|
<p id='sortText'>Sort by</p>
|
||||||
|
<p id='sortName'>Name</p>
|
||||||
|
<p id='sortDate'>Date</p>
|
||||||
|
<p id='sortSize'>Size</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input id="copy" readonly>
|
||||||
51
templates/pre_main.html
Normal file
51
templates/pre_main.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||||
|
<title>BinBin</title>
|
||||||
|
<link rel="icon" href="./assets/favicon.ico?v=2">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Saira+Condensed:300,400" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab:100,300" rel="stylesheet">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||||
|
<script src="https://use.fontawesome.com/c8d5486cd8.js"></script>
|
||||||
|
<script src="./js/tools.js"></script>
|
||||||
|
<script id="version">
|
||||||
|
scripts = {
|
||||||
|
'desktop': ['alert', 'desktop'],
|
||||||
|
'mobile': ['alert', 'mobile']
|
||||||
|
};
|
||||||
|
|
||||||
|
function isMobileDevice() {
|
||||||
|
return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
|
||||||
|
};
|
||||||
|
|
||||||
|
function setPage(method, html) {
|
||||||
|
body = get('body');
|
||||||
|
get('body').innerHTML = html;
|
||||||
|
scripts[method].forEach(function(ele) {
|
||||||
|
body.appendChild(element('script', {
|
||||||
|
src: `./js/${ele}.js`
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
get('head').removeChild(get('#version'));
|
||||||
|
};
|
||||||
|
|
||||||
|
var method = (isMobileDevice()) ? "mobile" : "desktop";
|
||||||
|
get('head').appendChild(element('link', {
|
||||||
|
rel: 'stylesheet',
|
||||||
|
href: `./css/${method}.css`
|
||||||
|
}));
|
||||||
|
|
||||||
|
$.get(`./main/${method}`).done(function(d) {
|
||||||
|
setPage(method, d);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user