From ed49d343f8363988bb3c366e5953275e15dc4206 Mon Sep 17 00:00:00 2001 From: Kenneth Jao Date: Thu, 6 Aug 2020 23:03:36 -0400 Subject: [PATCH] Moved to flask, added virtual databases and login --- .gitignore | 10 + favicon.ico => assets/favicon.ico | Bin binbin.py | 461 +++++++++++++++++++++++ binbin.wsgi | 1 + {desktop => css}/desktop.css | 171 +++++---- css/index.css | 103 +++++ {mobile => css}/mobile.css | 20 +- desktop/desktop.html | 74 ---- desktop/visualizer.js | 123 ------ download.php | 33 -- index.html | 39 -- js/alert.js | 38 ++ js/desktop.js | 234 ++++++++++++ js/drive.js | 0 js/index.js | 98 +++++ js/mobile.js | 290 ++++++++++++++ js/overlay.temp.js | 100 +++++ js/tools.js | 203 ++++++++++ main.php | 91 ----- mobile/mobile.html | 36 -- mobile/mobile.js | 606 ------------------------------ templates/404.html | 125 ++++++ templates/desktop.html | 41 ++ templates/drive.html | 21 ++ templates/index.html | 35 ++ templates/mobile.html | 35 ++ templates/pre_main.html | 51 +++ 27 files changed, 1953 insertions(+), 1086 deletions(-) create mode 100644 .gitignore rename favicon.ico => assets/favicon.ico (100%) create mode 100644 binbin.py create mode 100644 binbin.wsgi rename {desktop => css}/desktop.css (75%) create mode 100644 css/index.css rename {mobile => css}/mobile.css (88%) delete mode 100644 desktop/desktop.html delete mode 100644 desktop/visualizer.js delete mode 100644 download.php delete mode 100644 index.html create mode 100644 js/alert.js create mode 100644 js/desktop.js create mode 100644 js/drive.js create mode 100644 js/index.js create mode 100644 js/mobile.js create mode 100644 js/overlay.temp.js create mode 100644 js/tools.js delete mode 100644 main.php delete mode 100644 mobile/mobile.html delete mode 100644 mobile/mobile.js create mode 100644 templates/404.html create mode 100644 templates/desktop.html create mode 100644 templates/drive.html create mode 100644 templates/index.html create mode 100644 templates/mobile.html create mode 100644 templates/pre_main.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a8aa73 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +bin/* +include/* +lib/* +lib64 +__pycache__/* +share/* +pyvenv.cfg +key.txt +db.info +config.ini \ No newline at end of file diff --git a/favicon.ico b/assets/favicon.ico similarity index 100% rename from favicon.ico rename to assets/favicon.ico diff --git a/binbin.py b/binbin.py new file mode 100644 index 0000000..634d968 --- /dev/null +++ b/binbin.py @@ -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/') +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/', 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//') +def drive_path(): + pass + +@app.errorhandler(404) +def page_not_found(e): + return render_template('404.html'), 404 + + +# Temporary for development: +@app.route('/css/') +def css(path): + return send_from_directory('css', path) + +@app.route('/js/') +def js(path): + return send_from_directory('js', path) + +@app.route('/assets/') +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) \ No newline at end of file diff --git a/binbin.wsgi b/binbin.wsgi new file mode 100644 index 0000000..921f6f3 --- /dev/null +++ b/binbin.wsgi @@ -0,0 +1 @@ +from binbin import app as application diff --git a/desktop/desktop.css b/css/desktop.css similarity index 75% rename from desktop/desktop.css rename to css/desktop.css index 6aa4049..06fbc27 100644 --- a/desktop/desktop.css +++ b/css/desktop.css @@ -1,22 +1,21 @@ -@import url(https://fonts.googleapis.com/css?family=Abel); ::-webkit-scrollbar { - width: 12px; + width: 12px; } /* Track */ ::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); - -webkit-border-radius: 5px; - border-radius: 5px; + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + -webkit-border-radius: 5px; + border-radius: 5px; } /* Handle */ ::-webkit-scrollbar-thumb { - -webkit-border-radius: 5px; - border-radius: 5px; - background: rgba(255,255,255,0.7); - -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); + -webkit-border-radius: 5px; + border-radius: 5px; + background: rgba(255,255,255,0.7); + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); } ::-webkit-scrollbar-thumb:window-inactive { background: rgba(255,255,255,0.4); @@ -33,23 +32,20 @@ html { height: 100%; width: 100%; -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } body { - display: grid; height: 100%; overflow: hidden; padding: 0; margin: 0; color: white; - font-family: 'Open Sans Condensed', sans-serif; - grid-template-columns: 15% auto; - grid-template-rows: 8% auto; + font-family: 'Roboto Slab', sans-serif; } h1, h2, h3, h4, h5, p { @@ -61,11 +57,6 @@ a { color: #2EA8FF; } -#header1 h1 { - margin: auto; - font-size: 5vh; -} - .transition { -webkit-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 { display: grid; - background-color: #292828; + background-color: #1b1a1a; text-align: center; - grid-column: 1; - grid-row: 1; cursor: pointer; + height: 10vh; } -#header1 img { +#header1 h1 { margin: auto; - height: 80%; + font-size: 3em; + font-family: 'Roboto Slab', sans-serif; } #header2 { display: grid; - grid-template-columns: repeat(8, 1fr); + grid-template-rows: 1fr 1fr 1fr; background-color: #27262b; - grid-column: 2; + height: 10vh; +} + +#topNav { + display: grid; + grid-template-columns: repeat(8, 1fr); grid-row: 1; -} - -#header2 div { - margin: auto; - font-size: 150%; -} - -#header2 p { - cursor: pointer; - border-radius: 5px; - padding: 5%; + background-color: rgba(255,255,255,0.01); 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); } -#header2 i { - margin-left: 2%; -} - -#spectrum { - grid-column: 5; - grid-row: 1; -} #sidebar { position: relative; background-color: #27262b; - grid-column: 1; - grid-row: 2; + height: 100%; + display: inline-block; + width: 30vh; + font-family: 'Saira Condensed', sans-serif; } #sidebar span { @@ -145,7 +136,17 @@ a { height: 6vh; width: 100%; 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 { @@ -173,22 +174,27 @@ a { .navi p { margin: auto 0 auto 0; - font-size: 2vh; + font-size: 1em; grid-column: 3; + font-weight: 300; + font-size: 1.2em; } .naviInner p { margin: auto 0 auto 0; - font-size: 2vh; + font-size: 1em; grid-column: 2; } #mainContainer { - overflow: hidden; + position: absolute; + top: 0; background-color: #3e505a; font-family: 'Saira Condensed', sans-serif; - grid-column: 2; - grid-row: 2; + height: 100%; + min-width: 100vh; + width: calc(100vw - 30vh); + display: inline-block; } .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); } -#songList { - height: 100%; - color: white; - display: grid; - grid-template-columns: 100%; - grid-template-rows: 90% 10%; -} - #directory { display: grid; + height: 100%; grid-column: 1; grid-row: 1; grid-template-columns: 100%; - grid-template-rows: 1fr 2fr 20fr 5fr; + grid-template-rows: 1fr 2fr 25fr; } #directory p { - font-size: 150%; - padding: 1.5vh 2vh 1.5vh 2vh; + font-size: 1.2em; + padding: 0.6em; } canvas { @@ -241,24 +240,31 @@ canvas { #directoryHeader { display: grid; grid-template-columns: 60% 25% 10% 5%; - grid-template-rows: 100%; color: white; - background-color: #1c1c1c; - box-shadow: #242424 0 0 20px 0px; + background-color: #3c84a7; + box-shadow: #242424 0 0 2px 1px; } #directoryHeader p { display: grid; cursor: pointer; grid-template-columns: 19fr 1fr; - grid-template-rows: 100%; - padding: 2.3vh; + padding: .6em; + border-left: 1px solid #fefefe; +} + +#directoryHeader p:first-child { + border-left: none; } #directoryHeader p:hover { background-color: rgba(0,0,0,0.1); } +#directoryHeader span { + margin: auto 0 auto 0; +} + #directoryHeader i { margin: auto; display: none; @@ -282,16 +288,26 @@ canvas { background-color: rgba(255,255,255,0.1); } +.item:first-child { + border-top: 1px solid #222; +} + +.item:last-child { + margin-bottom: 25%; +} + .item .name { grid-column: 2; } .item .modified { grid-column: 3; + padding-left: 1.2em !important; } -.item .size: { +.item .size { grid-column: 4; + padding-left: 1.2em !important; } .item p { @@ -299,9 +315,8 @@ canvas { } .item div { - grid-column: 5; margin: auto; - font-size: 140%; + font-size: 1.2em; color: white; } @@ -318,7 +333,7 @@ canvas { } .fileIcon .fa { - padding: 1.3vh; + padding: .6em; } .fileIcon .fa:hover { diff --git a/css/index.css b/css/index.css new file mode 100644 index 0000000..0423d82 --- /dev/null +++ b/css/index.css @@ -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%;} +} \ No newline at end of file diff --git a/mobile/mobile.css b/css/mobile.css similarity index 88% rename from mobile/mobile.css rename to css/mobile.css index 7357915..dfbfdb8 100644 --- a/mobile/mobile.css +++ b/css/mobile.css @@ -16,7 +16,7 @@ body { padding: 0; margin: 0; color: white; - font-family: 'Open Sans Condensed', sans-serif; + font-family: 'Saira Condensed', sans-serif; grid-template-columns: 100%; grid-template-rows: 8% 6% auto; } @@ -72,10 +72,6 @@ a { box-shadow: 1px 0px 12px 1px black; } -#sidebar div:nth-child(2) { - margin-top: 20%; -} - #sidebar span { font-size: 110%; padding: 5%; @@ -97,6 +93,16 @@ a { 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 { background-color: rgba(0,0,0,0.15); } @@ -123,6 +129,7 @@ a { .navi p { margin: auto 0 auto 0; font-size: 2vh; + font-weight: 300; grid-column: 3; } @@ -168,9 +175,10 @@ a { grid-row: 1; grid-column: 2; font-size: 120%; + font-weight: 300; } -.item .modified { +.item .otherInfo { grid-row: 2; grid-column: 2; font-size: 80%; diff --git a/desktop/desktop.html b/desktop/desktop.html deleted file mode 100644 index 57f89a6..0000000 --- a/desktop/desktop.html +++ /dev/null @@ -1,74 +0,0 @@ - -
-

BinBin

-
-
-
-

Spectrum

-
-
- -
-
-
-
-

a

-
-
-

Name - - -

-

Date Modified - - -

-

Size - - -

-
-
- -
- -
-
-
-
-

-
-
- -
-
-
-
- - - -
-
-

-:--

- -

-:--

-
-
-
- - -
-
- - -
- -
-
-
- - \ No newline at end of file diff --git a/desktop/visualizer.js b/desktop/visualizer.js deleted file mode 100644 index 182f2fc..0000000 --- a/desktop/visualizer.js +++ /dev/null @@ -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); - } -} \ No newline at end of file diff --git a/download.php b/download.php deleted file mode 100644 index c77d33c..0000000 --- a/download.php +++ /dev/null @@ -1,33 +0,0 @@ - \ No newline at end of file diff --git a/index.html b/index.html deleted file mode 100644 index f4528b3..0000000 --- a/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - BinBin - - - - - - - - - - - - diff --git a/js/alert.js b/js/alert.js new file mode 100644 index 0000000..dc4b47c --- /dev/null +++ b/js/alert.js @@ -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); +} diff --git a/js/desktop.js b/js/desktop.js new file mode 100644 index 0000000..ec477c5 --- /dev/null +++ b/js/desktop.js @@ -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(); diff --git a/js/drive.js b/js/drive.js new file mode 100644 index 0000000..e69de29 diff --git a/js/index.js b/js/index.js new file mode 100644 index 0000000..4d2cfa9 --- /dev/null +++ b/js/index.js @@ -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(); +}); \ No newline at end of file diff --git a/js/mobile.js b/js/mobile.js new file mode 100644 index 0000000..f8ee60c --- /dev/null +++ b/js/mobile.js @@ -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(); \ No newline at end of file diff --git a/js/overlay.temp.js b/js/overlay.temp.js new file mode 100644 index 0000000..f7555f0 --- /dev/null +++ b/js/overlay.temp.js @@ -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); +} \ No newline at end of file diff --git a/js/tools.js b/js/tools.js new file mode 100644 index 0000000..aeea1aa --- /dev/null +++ b/js/tools.js @@ -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); + } +}; \ No newline at end of file diff --git a/main.php b/main.php deleted file mode 100644 index 0b9422b..0000000 --- a/main.php +++ /dev/null @@ -1,91 +0,0 @@ -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; -} - -?> \ No newline at end of file diff --git a/mobile/mobile.html b/mobile/mobile.html deleted file mode 100644 index 582ca94..0000000 --- a/mobile/mobile.html +++ /dev/null @@ -1,36 +0,0 @@ - - -
-

BinBin

-

Name

- -
- -
-
-
-
-
-

Sort by...

- Download -
- - - \ No newline at end of file diff --git a/mobile/mobile.js b/mobile/mobile.js deleted file mode 100644 index 4b16a26..0000000 --- a/mobile/mobile.js +++ /dev/null @@ -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); \ No newline at end of file diff --git a/templates/404.html b/templates/404.html new file mode 100644 index 0000000..6ebab2c --- /dev/null +++ b/templates/404.html @@ -0,0 +1,125 @@ + + + + + BinBin + + + + + + + + + +

404

+ + + + + diff --git a/templates/desktop.html b/templates/desktop.html new file mode 100644 index 0000000..73d9c5b --- /dev/null +++ b/templates/desktop.html @@ -0,0 +1,41 @@ + +
+
+
+
Logout
+
+
+
+
+

a

+
+
+

+ Name + + +

+

+ Date Modified + + +

+

+ Size + + +

+
+
+ +
+ +
+
+ diff --git a/templates/drive.html b/templates/drive.html new file mode 100644 index 0000000..2a0ab31 --- /dev/null +++ b/templates/drive.html @@ -0,0 +1,21 @@ + + + + + BinBin + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..be5c488 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,35 @@ + + + + + BinBin + + + + + + + + + + + +
+
+

BinBin

+
+

Username:

+ +

Password:

+ +
+
+ +
+
+
+ + + + + diff --git a/templates/mobile.html b/templates/mobile.html new file mode 100644 index 0000000..6a32c9c --- /dev/null +++ b/templates/mobile.html @@ -0,0 +1,35 @@ + +
+

+

Name

+ +
+ +
+
+
+
+
+

Sort by...

+ Download +
+ + \ No newline at end of file diff --git a/templates/pre_main.html b/templates/pre_main.html new file mode 100644 index 0000000..e5d43e5 --- /dev/null +++ b/templates/pre_main.html @@ -0,0 +1,51 @@ + + + + + + BinBin + + + + + + + + + + + + + + \ No newline at end of file