first working version

This commit is contained in:
Robin Linus 2015-12-26 13:33:16 +01:00
parent f1ad168e40
commit bda1a15750
24 changed files with 543 additions and 206 deletions

View file

@ -52,12 +52,10 @@
</file-input>
</template>
</div>
<div hidden$="{{buddies.length}}" class="explanation">
Open this page on another device
<wbr>to share files.
<div hidden$="{{buddies.0}}" class="explanation">
Open this page on other devices<br> to send files.
</div>
<personal-avatar class="me"></personal-avatar>
<!-- <iron-ajax id="ajax" auto url="https://yawim.com/findbuddies/{{me}}" handle-as="json" last-response="{{buddies}}"></iron-ajax> -->
</template>
<script>
'use strict';
@ -66,30 +64,11 @@
properties: {
buddies: {
type: Array,
value: []
notify: true
},
me: {
type: String,
}
},
attached: function() {
//Ask server every second for changes
var ajax = this.$.ajax;
function request() {
//ajax.generateRequest();
}
var intervalId = setInterval(request, 1000);
document.addEventListener('visibilitychange', function() {
if (document.hidden) {
clearInterval(intervalId);
intervalId = 0;
} else {
if (!intervalId) {
intervalId = setInterval(request, 1000);
}
}
});
},
},
_fileSelected: function(e) {
var peerId = e.model.item.peerId;

View file

@ -13,11 +13,11 @@
width: 80px;
height: 80px;
color: #4285f4;
margin-bottom: 6px;
}
.paper-font-body1 {
font-size: 13px;
margin-top: 6px;
}
.discover {
@ -26,7 +26,7 @@
</style>
<iron-icon icon="chat:wifi-tethering"></iron-icon>
<div class="paper-font-body1">
SnapDrop lets you share instantly with people near by.
Snapdrop lets you share instantly with people near by.
</div>
<div class="paper-font-body1 discover">
Allow me to be discovered by: Everyone in this network.

View file

@ -7,7 +7,7 @@
@apply(--layout-vertical);
@apply(--layout-center);
width: 120px;
height: 120px;
height: 152px;
}
paper-icon-button {
@ -45,7 +45,7 @@
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
margin: 4px;
margin-top: 4px;
}
</style>
<paper-icon-button icon="{{_displayIcon}}"></paper-icon-button>
@ -85,7 +85,6 @@
if (contact.type === 'tablet') {
return 'chat:tablet-mac';
}
return 'chat:desktop-mac';
},
attached: function() {

View file

@ -2,14 +2,14 @@
<link rel="import" href="../bower_components/platinum-sw/platinum-sw-register.html">
<link rel="import" href="../bower_components/paper-toast/paper-toast.html">
<link rel="import" href="../bower_components/paper-progress/paper-progress.html">
<link rel="import" href="../bower_components/neon-animation/neon-animated-pages.html">
<!-- Configure your routes here
<link rel="import" href="routing.html">
-->
<!-- Add your elements here -->
<link rel="import" href="../styles/app-theme.html">
<link rel="import" href="x-cards/x-card.html">
<link rel="import" href="x-cards/x-cards.html">
<link rel="import" href="buddy-finder/buddy-finder.html">
<link rel="import" href="p2p-network/connection-wrapper.html">
<link rel="import" href="file-sharing/file-receiver.html">

View file

@ -17,13 +17,14 @@
z-index: 101;
}
b {
.filename {
word-break: break-all;
word-break: break-word;
}
</style>
<paper-dialog id="dialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop modal>
<h2>Download File</h2>
<p><b>{{file.name}}</b></p>
<p><b class="filename">{{file.name}}</b></p>
<div class="buttons">
<paper-button dialog-dismiss on-tap="_decline">Discard</paper-button>
<paper-button dialog-confirm on-tap="_accept" autofocus>Download</paper-button>
@ -31,11 +32,11 @@
</paper-dialog>
<paper-dialog id="download" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop modal>
<h2>File Received</h2>
<p>Right Click and "Save as"...</p>
<p>Open File or Right Click and "Save as"...</p>
<div class="buttons">
<paper-button dialog-dismiss>Discard</paper-button>
<a href="{{dataUri}}" target="_blank">
<paper-button dialog-confirm autofocus>Download</paper-button>
<paper-button dialog-confirm autofocus>Open File</paper-button>
</a>
</div>
</paper-dialog>

File diff suppressed because one or more lines are too long

View file

@ -7,8 +7,11 @@ Chat.FileSelectionBehavior = {
console.log('no files selected...');
return;
}
for (var i = 0; i < files.length; i++) {
var file = files[i];
this._fileSelected(files[0]); //single select
//files.forEach(this._fileSelected.bind(this)); //multi-select
},
_fileSelected: function(file) {
if (file) {
this.fire('file-selected', {
file: file,
name: file.name

View file

@ -8,27 +8,17 @@
<script>
'use strict';
(function() {
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
var webRTCSupported = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || window.webkitRTCPeerConnection;
window.webRTCSupported = !!(window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || window.webkitRTCPeerConnection);
function rtcConnectionSupported(peerId) {
return webRTCSupported && (peerId.indexOf('rtc_') === 0);
return window.webRTCSupported && (peerId.indexOf('rtc_') === 0);
}
Polymer({
is: 'connection-wrapper',
properties: {
me: {
notify: true,
value: (webRTCSupported ? 'rtc_' : 'ws_') + guid()
}
notify: true
},
},
behaviors: [Chat.FileTransferProtocol],
_sendFile: function(toPeer, file) {
@ -50,9 +40,17 @@
if (!rtcConnectionSupported(toPeer)) {
callback();
} else {
this.$.p2p.connectToPeer(toPeer,callback);
this.$.p2p.connectToPeer(toPeer, callback);
}
},
_onHandshake: function(event) {
var me = event.uuid;
console.log('i am');
this.set('me', me);
if (window.webRTCSupported) {
this.$.p2p.initialize();
}
}
});
})();
</script>

View file

@ -22,6 +22,9 @@ Chat.FileTransferProtocol = {
console.log('FTP received sysMsg:', msg);
switch (msg.type) {
case 'handshake':
this._onHandshake(msg);
break;
case 'offer':
this._onOffered(msg);
break;

View file

@ -9,8 +9,7 @@
is: 'p2p-network',
properties: {
me: {
type: String,
notify: true,
type: String
}
},
attached: function() {
@ -22,16 +21,24 @@
this._peer.destroy();
}
}.bind(this);
this._initialize();
},
_initialize: function() {
var options = {
host: 'yawim.com',
port: 443,
path: 'peerjs',
secure: true
};
this._peer = new Peer(this.me,options);
initialize: function() {
var options;
if (window.debug) {
options = {
host: window.location.hostname,
port: 3002,
path: 'peerjs'
};
} else {
options = {
host: 'snapdrop.net',
port: 443,
path: 'peerjs',
secure: true
};
}
this._peer = new Peer(this.me, options);
this._peer.on('open', function(id) {
console.log('My peer ID is: ' + id);
this.set('me', id);
@ -53,12 +60,10 @@
if (err.message.indexOf('Lost connection to server') > -1) {
this._peer.destroy();
this.set('me', this.me);
this._initialize();
this.async(this._initialize, 3000);
return;
}
}.bind(this));
},
connect: function(c) {
@ -140,7 +145,7 @@
conns.forEach(function(conn) {
if (conn.label === 'file') {
conn.send(file);
console.log('file send');
console.log('file send via WebRTC');
}
}.bind(this));
}

View file

@ -15,13 +15,13 @@
this.init();
},
init: function() {
var websocketUrl = (window.location.protocol === 'https:' ? 'wss://' : 'ws://') + document.location.hostname + ':9001';
var websocketUrl = (window.debug ? 'ws://' + window.location.hostname + ':3002' : 'wss://snapdrop.net') + '/binary';
this.client = new BinaryClient(websocketUrl);
this.client.on('stream', function(stream, meta) {
// collect stream data
var parts = [];
stream.on('data', function(data) {
console.log('part received', meta, data);
//console.log('part received', meta, data);
if (data.isSystemEvent) {
if (meta) {
data.from = meta.from;
@ -45,22 +45,22 @@
}.bind(this));
}.bind(this));
this.client.on('open', function(e) {
this.cancelAsync(this.reconnectTimer);
console.log(e);
this.client.send({}, {
handshake: this.me
serverMsg: 'rtc-support',
rtc: window.webRTCSupported
});
}.bind(this));
this.client.on('error', function(e) {
console.log(e);
});
this._reconnect(e);
}.bind(this));
this.client.on('close', function(e) {
console.log(e);
//try to reconnect after 3s
this.async(this.init, 3000);
this._reconnect(e);
}.bind(this));
},
_sendFile: function(toPeer, file) {
console.log('send file!', file);
console.log('send file via WebSocket', file);
this.client.send(file.file, {
name: file.file.name,
type: file.file.type,
@ -76,6 +76,11 @@
this.client.send(event, {
toPeer: toPeer
});
},
_reconnect: function(e) {
console.log('disconnected', e);
//try to reconnect after 3s
this.reconnectTimer = this.async(this.init, 3000);
}
});
</script>

View file

@ -0,0 +1,138 @@
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../../bower_components/neon-animation/neon-shared-element-animatable-behavior.html">
<link rel="import" href="../../bower_components/neon-animation/neon-animations.html">
<link rel="import" href="../../bower_components/paper-styles/paper-styles-classes.html">
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
<dom-module id="x-card">
<template>
<style>
:host {
display: block;
overflow: hidden;
color: white;
z-index: 3
}
#placeholder {
opacity: 0;
background-color: #4285f4;
@apply(--layout-fit);
}
paper-icon-button {
position: absolute;
top: 16px;
right: 16px;
z-index: 2;
}
#container {
@apply(--layout-fit);
@apply(--layout-vertical);
@apply(--layout-center-center);
background-color: #4285f4;
padding: 64px 32px 64px 32px;
box-sizing: border-box;
}
iron-icon {
width: 80px;
height: 80px;
}
.paper-font-subhead {
text-align: center;
}
a {
text-decoration: none;
color: white;
@apply(--layout-self-end);
}
.center {
@apply(--layout-vertical);
@apply(--layout-center-center);
}
#footer {
position: absolute;
left: 50%;
margin-left: -160px;
width: 320px;
bottom: 24px;
text-align: center;
}
</style>
<paper-icon-button id="btn" icon="chat:close" on-tap="_switch"></paper-icon-button>
<div id="placeholder"></div>
<div id="container">
<div class="center">
<iron-icon icon="chat:wifi-tethering"></iron-icon>
<div class="paper-font-headline">Snapdrop</div>
<div class="paper-font-subhead">The easiest way to send files across devices.</div>
</div>
<span id="footer">Built with &#9829; by <a href="mailto:robin@capira.de">Robin Linus</a></span>
</div>
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'x-card',
behaviors: [
Polymer.NeonSharedElementAnimatableBehavior
],
properties: {
animationConfig: {
value: function() {
return {
'entry': [{
name: 'ripple-animation',
id: 'ripple',
toPage: this
}, {
name: 'fade-out-animation',
node: this.$.placeholder,
timing: {
delay: 250
}
}, {
name: 'fade-in-animation',
node: this.$.container,
timing: {
delay: 50
}
}],
'exit': [{
name: 'opaque-animation',
node: this.$.placeholder
}, {
name: 'fade-out-animation',
node: this.$.container,
timing: {
duration: 0
}
}, {
name: 'reverse-ripple-animation',
id: 'reverse-ripple',
fromPage: this
}]
};
}
},
sharedElements: {
value: function() {
return {
'ripple': this.$.placeholder,
'reverse-ripple': this.$.placeholder
};
}
}
},
_switch: function() {
document.querySelector('#pages').select(0);
}
});
})();
</script>

View file

@ -0,0 +1,83 @@
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../../bower_components/neon-animation/neon-shared-element-animatable-behavior.html">
<link rel="import" href="../../bower_components/neon-animation/neon-animations.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<dom-module id="x-cards">
<template>
<style>
:host {
display: block;
overflow: hidden;
}
#placeholder {
opacity: 0;
background-color: grey;
@apply(--layout-fit);
}
paper-icon-button {
position: absolute;
top: 16px;
right: 16px;
z-index: 2;
color: #313131;
}
paper-icon-button:hover {
color: #4285f4;
}
</style>
<div id="placeholder"></div>
<div id="container">
<paper-icon-button id="btn" icon="chat:info-outline" on-tap="_switch"></paper-icon-button>
<content select="div"></content>
</div>
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'x-cards',
behaviors: [
Polymer.NeonSharedElementAnimatableBehavior
],
properties: {
animationConfig: {
value: function() {
return {
'entry': [{
name: 'reverse-ripple-animation',
id: 'reverse-ripple',
toPage: this
}],
'exit': [{
name: 'fade-out-animation',
node: this.$.container,
timing: {
delay: 150,
duration: 0
}
}, {
name: 'ripple-animation',
id: 'ripple',
fromPage: this
}]
};
}
},
sharedElements: {
value: function() {
return {
'ripple': this.$.btn,
'reverse-ripple': this.$.btn
};
}
}
},
_switch: function() {
document.querySelector('#pages').select(1);
}
});
})();
</script>