Import files from Yawim

This commit is contained in:
Robin Linus 2015-12-18 17:43:46 +01:00
parent 370003835e
commit dd4809f519
18 changed files with 994 additions and 116 deletions

View file

@ -0,0 +1,24 @@
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
<dom-module id="buddy-finder-button">
<template>
<style>
:host {
display: block;
}
paper-icon-item {
height: 60px;
}
</style>
<paper-icon-item>
<iron-icon icon="chat:wifi-tethering" item-icon></iron-icon>
Find People
</paper-icon-item>
</template>
<script>
'use strict';
Polymer({
is: 'buddy-finder-button'
});
</script>
</dom-module>

View file

@ -0,0 +1,85 @@
<link rel="import" href="../../../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="../../../bower_components/paper-styles/paper-styles.html">
<link rel="import" href="../contact-item/contact-item.html">
<link rel="import" href="../file-sharing/share-area.html">
<link rel="import" href="user-avatar.html">
<dom-module id="buddy-finder">
<template>
<style>
:host {
display: block;
background-color: white;
@apply(--layout-fit);
@apply(--layout-vertical);
@apply(--layout-center-center);
border-left: 1px solid #ccc;
}
.paper-font-display1 {
color: black;
text-align: center;
margin-bottom: 16px;
display: none;
}
.buddies {
z-index: 1;
}
.buddy {
cursor: pointer;
}
.circles {
position: absolute;
bottom: -50px;
left: 50%;
width: 1140px;
margin-left: -570px;
height: 700px;
transform-origin: 570px 570px;
animation: grow 1.5s ease-out;
fill: transparent;
}
.me {
position: absolute;
bottom: 30px;
left: 50%;
margin-left: -60px;
}
</style>
<div class="paper-font-display1">People near by</div>
<div class="buddies">
<template is="dom-repeat" items="{{buddies}}">
<share-area>
<user-avatar on-tap="_connect" contact="{{item.peerId}}" class="buddy"></user-avatar>
</share-area>
</template>
</div>
<user-avatar contact="{{me}}" class="me"></user-avatar>
<iron-ajax auto url="https://yawim.com/findbuddies/{{me}}" handle-as="json" last-response="{{buddies}}"></iron-ajax>
<svg class="circles" viewBox="-0.5 -0.5 1140 700">
<circle class="circle" cx="570" cy="570" r="120" stroke="rgba(160,160,160,.4)"></circle>
<circle class="circle" cx="570" cy="570" r="210" stroke="rgba(160,160,160,.35)"></circle>
<circle class="circle" cx="570" cy="570" r="300" stroke="rgba(160,160,160,.3)"></circle>
<circle class="circle" cx="570" cy="570" r="390" stroke="rgba(160,160,160,.2)"></circle>
<circle class="circle" cx="570" cy="570" r="480" stroke="rgba(160,160,160,.15)"></circle>
</svg>
</template>
<script>
'use strict';
Polymer({
is: 'buddy-finder',
properties: {
buddies: Array,
me: {
type: String,
}
},
_connect: function(e) {
Polymer.dom(document).querySelector('x-app').p2p.connectToPeer(e.model.item.peerId);
}
});
</script>
</dom-module>

View file

@ -0,0 +1,43 @@
<link rel="import" href="../contact-item/anonymous-contact-behavior.html">
<dom-module id="user-avatar">
<template>
<style>
:host {
display: block;
@apply(--layout-vertical);
@apply(--layout-center);
width: 120px;
}
.avatar {
display: inline-block;
width: 52px;
height: 52px;
border-radius: 50%;
overflow: hidden;
background: #ccc;
@apply(--shadow-elevation-2dp);
}
.paper-font-subhead{
text-align: center;
}
</style>
<div class="avatar" id="avatar" item-icon></div>
<div class="paper-font-subhead">{{_displayName}}</div>
</template>
<script>
'use strict';
Polymer({
is: 'user-avatar',
behaviors:[Chat.AnonymousContactBehavior],
observers:['_computeBackgroundImg(contact.*)'],
_computeBackgroundImg:function(){
console.log('avatar changed');
var avatar = this.anonymousAccount(this.contact).avatar;
var style = this.$.avatar.style;
style.backgroundImage='url('+avatar.url+')';
style.backgroundPosition=avatar.left+'px '+avatar.top+'px';
}
});
</script>
</dom-module>

View file

@ -0,0 +1,337 @@
<script>
'use strict';
var Chat = window.Chat || {};
var djb2Code = function(str) {
var hash = 5381;
for (var i = 0; i < str.length; i++) {
var character = str.charCodeAt(i);
hash = ((hash << 5) + hash) + character; /* hash * 33 + c */
}
return hash > 0 ? hash : -hash;
};
var animals = [
'Adelie',
'Penguin',
'Akita',
'Bulldog',
'Ant',
'Fox',
'Hare',
'Wolf',
'Terrier',
'Avocet',
'Baboon',
'Camel',
'Badger',
'Barb',
'Basenji',
'Basking',
'Bat',
'Beagle',
'Bear',
'Collie',
'Beaver',
'Beetle',
'Bichon',
'Bird',
'Birman',
'Bison',
'Bobcat',
'Bombay',
'Bongo',
'Bonobo',
'Booby',
'Boykin',
'Budgie',
'Buffalo',
'Burmese',
'Fish',
'Caiman',
'Lizard',
'Canaan',
'Caracal',
'Cat',
'Catfish',
'Cesky',
'Fousek',
'Chamois',
'Cheetah',
'Chicken',
'Chinook',
'Cichlid',
'Leopard',
'Clumber',
'Coati',
'Coral',
'Tamarin',
'Cougar',
'Cow',
'Coyote',
'Crab',
'Macaque',
'Crane',
'Cuscus',
'Frog',
'Deer',
'Bracke',
'Dhole',
'Dingo',
'Discus',
'Dodo',
'Dog',
'Dogo',
'Dolphin',
'Donkey',
'Drever',
'Duck',
'Dugong',
'Dunker',
'Dusky',
'Eagle',
'Earwig ',
'Gorilla',
'Echidna',
'Emu',
'Falcon',
'Fennec',
'Ferret',
'Spitz',
'Fly',
'Fossa',
'Gecko',
'Gerbil',
'Gharial',
'Gibbon',
'Giraffe',
'Goat',
'Oriole',
'Goose',
'Gopher',
'Grouse',
'Guppy',
'Shark',
'Hamster',
'Harrier',
'Heron',
'Horse',
'Human',
'Hyena',
'Ibis',
'Iguana',
'Impala',
'Indri',
'Insect',
'Setter',
'Jackal',
'Jaguar',
'Kakapo',
'Kiwi',
'Koala',
'Lemming',
'Lemur',
'Liger',
'Lion',
'Llama',
'Lobster',
'Owl',
'Lynx',
'Mayfly',
'Meerkat',
'Molly',
'Mongrel',
'Monkey',
'Moorhen',
'Moose',
'Mouse',
'Mule',
'Numbat',
'Ocelot',
'Octopus',
'Okapi',
'Opossum',
'Ostrich',
'Otter',
'Oyster',
'Panther',
'Parrot',
'Peacock',
'Pelican',
'Persian',
'Pig',
'Piranha',
'Pointer',
'Poodle',
'Possum',
'Prawn',
'Puffin',
'Pug',
'Puma',
'Pygmy',
'Quail',
'Quetzal',
'Quokka',
'Quoll',
'Rabbit',
'Raccoon',
'Ragdoll',
'Rat',
'Robin',
'Saola',
'Seal',
'Serval',
'Sheep',
'Shrimp',
'Siamese',
'Skunk',
'Sloth',
'Snail',
'Snake',
'Somali',
'Sparrow',
'Dogfish',
'Sponge',
'Squid',
'Stoat',
'Swan',
'Tang',
'Tapir',
'Tarsier',
'Termite',
'Tetra',
'Tiffany',
'Tiger',
'Toucan',
'Tuatara',
'Turkey',
'Uakari',
'Uguisu',
'Vulture',
'Wallaby',
'Walrus',
'Warthog',
'Wasp',
'Weasel',
'Whippet',
'Wombat',
'Wrasse',
'Yak',
'Yorkie',
'Zebra',
'Zebu',
'Zonkey',
'Zorse'
];
var bb = [
'Walter White',
'Skyler White',
'Jesse Pinkman',
'Hank Schrader',
'Marie Schrader',
'Walter White, Jr.',
'Saul Goodman',
'Gustavo Fring',
'Mike Ehrmantraut',
'Lydia Rodarte-Quayle',
'Todd Alquist',
'Steven Gomez',
'Detectives Kalanchoe & Munn',
'George Merkert',
'Sac Ramey',
'Tim Roberts',
'Maximino Arciniega',
'Gale Boetticher',
'Duane Chow',
'Ron Forenall',
'Barry Goodman',
'Tyrus Kitt',
'Chris Mara',
'Dennis Markowski',
'Victor',
'Dan Wachsberger',
'Don Eladio Vuente',
'Juan Bolsa',
'Hector Salamanca',
'Tuco Salamanca',
'Leonel Salamanca',
'Marco Salamanca',
'Gonzo',
'Emilio Koyama',
'Krazy-8 Molina',
'Jack Welker',
'Andrea Cantillo',
'Brock Cantillo',
'Jane Margolis',
'Brandon Mayhew',
'Combo Ortega',
'Skinny Pete',
'Adam Pinkman',
'Mrs. Pinkman',
'Jake Pinkman',
'Wendy',
'Huell Babineaux',
'Ed',
'Francesca',
'Patrick Kuby',
'Hugo Archuleta',
'Ted Beneke',
'Clovis',
'Louis Corbett',
'Dr. Delcavoli',
'Lawson',
'Donald Margolis',
'Carmen Molina',
'Old Joe',
'Pamela',
'Gretchen Schwartz',
'Elliott Schwartz',
'Drew Sharp',
'Spooge',
'Holly White',
'Bogdan Wolynetz'
];
Chat.AnonymousContactBehavior = {
properties: {
contact: {
type: Object,
notify: true
},
_displayName: {
computed: '_computeDisplayName(contact)'
}
},
_computeDisplayName: function(contact) {
if (contact === undefined || contact === null) {
return 'connecting...';
}
if (contact === 'error' || contact === 'invite') {
return '';
}
if (!contact.name) {
return this.anonymousAccount(contact).name;
}
return contact.name;
},
get names() {
return bb;
},
anonymousAccount: function(contact) {
if (contact && !contact.name) {
var peer = contact.peer || contact;
var hash = djb2Code(peer);
var i = hash % this.names.length;
var name = this.names[i];
var marginTop = i % 2;
var marginLeft = Math.floor(i / 2) % 5;
return {
name: name,
peer: peer,
avatar: {
url: 'images/avatars.jpg',
left: -14 + 80 * marginLeft,
top: -19 + 95 * marginTop
}
};
}
}
};
</script>

View file

@ -1,35 +1,7 @@
<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<!-- Iron elements -->
<link rel="import" href="../bower_components/iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../bower_components/iron-pages/iron-pages.html">
<link rel="import" href="../bower_components/iron-selector/iron-selector.html">
<!-- Paper elements -->
<link rel="import" href="../bower_components/paper-drawer-panel/paper-drawer-panel.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../bower_components/paper-item/paper-item.html">
<link rel="import" href="../bower_components/paper-material/paper-material.html">
<link rel="import" href="../bower_components/paper-menu/paper-menu.html">
<link rel="import" href="../bower_components/paper-scroll-header-panel/paper-scroll-header-panel.html">
<link rel="import" href="../bower_components/paper-styles/paper-styles-classes.html">
<link rel="import" href="../bower_components/paper-toast/paper-toast.html">
<link rel="import" href="../bower_components/paper-toolbar/paper-toolbar.html">
<!-- Uncomment next block to enable Service Worker Support (2/2) -->
<!--
<link rel="import" href="../bower_components/platinum-sw/platinum-sw-cache.html">
<link rel="import" href="../bower_components/platinum-sw/platinum-sw-register.html">
-->
<link rel="import" href="../bower_components/paper-toast/paper-toast.html">
<!-- Configure your routes here -->
<link rel="import" href="routing.html">
@ -37,5 +9,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<!-- Add your elements here -->
<link rel="import" href="../styles/app-theme.html">
<link rel="import" href="../styles/shared-styles.html">
<link rel="import" href="my-greeting/my-greeting.html">
<link rel="import" href="my-list/my-list.html">
<link rel="import" href="buddy-finder/buddy-finder.html">
<link rel="import" href="p2p-network/p2p-network.html">

View file

@ -0,0 +1,37 @@
<script>
'use strict';
Chat = window.Chat || {};
Chat.FileDropBehavior = {
attached: function() {
var dropZone = this;
// Optional. Show the copy icon when dragging over. Seems to only work for chrome.
dropZone.addEventListener('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
this.style.transform = 'scale(1.2)';
});
// Get file data on drop
dropZone.addEventListener('drop', function(e) {
e.stopPropagation();
e.preventDefault();
var files = e.dataTransfer.files; // Array of all files
for (var i = 0; i < files.length; i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = function(e2) {
// finished reading file data.
console.log('file dropped');
this.fire('file-uploaded', {
url: e2.target.result,
name: file.name
});
}.bind(this);
reader.readAsDataURL(file); // start reading the file data.
}
});
}
}
</script>

View file

@ -0,0 +1,36 @@
<script>
'use strict';
Chat.FileSharingButtonBehavior = {
properties: {
file: {
type: String
}
},
get fileInput(){
var fileInput=document.querySelector('input');
},
attached: function() {
this.$.file.onchange = function(value) {
this.file = this.$.file.value;
console.log(this.file);
var files = this.$.file.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = function(e2) {
// finished reading file data.
console.log('file dropped');
this.fire('file-uploaded', {
url: e2.target.result,
name: file.name
});
}.bind(this);
reader.readAsDataURL(file); // start reading the file data.
}
}.bind(this);
},
_upload: function() {
this.$.file.click();
}
};
</script>

View file

@ -0,0 +1,58 @@
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="file-reader.html">
<dom-module id="file-sharing-button">
<template>
<style>
:host {
display: inline-block;
}
#file {
margin: 0;
opacity: 0;
padding: 0;
position: absolute;
top: -10000px;
}
</style>
<paper-icon-button id="btn" icon="chat:attach-file" on-tap="_upload"></paper-icon-button>
<input id="file" type="file" value="{{file::input}}">
</template>
<script>
'use strict';
Polymer({
is: 'file-sharing-button',
properties: {
file: {
type: String
}
},
attached: function() {
this.$.file.onchange = function(value) {
this.file = this.$.file.value;
console.log(this.file);
var files = this.$.file.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
var reader = new FileReader();
reader.onload = function(e2) {
// finished reading file data.
console.log('file dropped');
this.fire('file-uploaded', {
url: e2.target.result,
name: file.name
});
}.bind(this);
reader.readAsDataURL(file); // start reading the file data.
}
}.bind(this);
},
_upload: function() {
this.$.file.click();
}
});
</script>
</dom-module>

View file

@ -0,0 +1,48 @@
<link rel="import" href="../../../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="file-reader.html">
<dom-module id="file-sharing">
<template>
<style>
:host {
display: block;
position: fixed;
z-index: 100;
}
</style>
<paper-dialog id="dialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdro>
<h2>File Received</h2>
<p>You received file {{file.name}}</p>
<div class="buttons">
<paper-button dialog-dismiss>Dismiss</paper-button>
<paper-button dialog-confirm on-tap="_download">Download</paper-button>
</div>
</paper-dialog>
</template>
<script>
'use strict';
Polymer({
is: 'file-sharing',
attached: function() {
document.querySelector('x-app').addEventListener('file-received', function(e) {
this.fileReceived(e.detail);
}.bind(this), false);
},
fileReceived: function(file) {
this.set('file', file);
this.$.dialog.open();
},
_download: function() {
var link = document.createElement('a');
link.download = this.file.name;
// Construct the uri
var uri = this.file.url;
link.href = uri;
document.body.appendChild(link);
link.click();
// Cleanup the DOM
document.body.removeChild(link);
//delete link;
}
});
</script>
</dom-module>

View file

@ -0,0 +1,18 @@
<link rel="import" href="file-drop-behavior.html">
<dom-module id="share-area">
<template>
<style>
:host {
display: block;
}
</style>
<content></content>
</template>
<script>
'use strict';
Polymer({
is: 'share-area',
behaviors: [Chat.FileDropBehavior]
});
</script>
</dom-module>

View file

@ -0,0 +1 @@
<script src="../../../bower_components/peerjs/peer.min.js"></script>

View file

@ -0,0 +1,245 @@
<link rel="import" href="p2p-network-imports.html">
<link rel="import" href="../../../bower_components/iron-localstorage/iron-localstorage.html">
<dom-module id="p2p-network">
<template>
<iron-localstorage name="peer-id" value="{{me}}" id="meStorage">
</iron-localstorage>
<iron-localstorage name="peers" value="{{peers}}" on-iron-localstorage-load-empty="initializeDefaultPeers">
</iron-localstorage>
</template>
<script>
'use strict';
Polymer({
is: 'p2p-network',
properties: {
me: {
type: String,
notify: true,
observer: '_initialize'
},
peers: {
type: Array,
value: [],
notify: true,
},
peer: {
value: 'loading',
notify: true
}
},
attached: function() {
this._connectedPeers = {};
this._initCallbacks = [];
this._unsendMsgs = {};
window.onunload = window.onbeforeunload = function() {
if (!!this._peer && !this._peer.destroyed) {
this._peer.destroy();
}
}.bind(this);
},
_initialize: function(me) {
if (!this.initialized && this.$.meStorage._loaded) {
var options = {
host: 'yawim.com',
port: 443 ,
path:'peerjs',
secure: true
};
me = me ? me : undefined;
me = me === 'null' ? undefined : me;
this._peer = new Peer(me, options);
this._peer.on('open', function(id) {
console.log('My peer ID is: ' + id);
this.set('me', id);
this._peerOpen = true;
this._initCallbacks.forEach(function(cb) {
cb();
});
}.bind(this));
this._peer.on('connection', this.connect.bind(this));
this._peer.on('error', function(err) {
console.error(err);
//ugly hack to find out error type
if (err.message.indexOf('Could not connect to peer') > -1) {
delete this._connectedPeers[this.peer];
this.set('peer', 'error');
return;
}
if (err.message.indexOf('Lost connection to server') > -1) {
this._peer.destroy();
this.initialized = false;
this._connectedPeers = {};
this.set('me', me);
this._initialize(this.me);
return;
}
}.bind(this));
}
this.initialized = true;
},
connect: function(c) {
var peer = c.peer;
if (c.label === 'chat') {
c.on('data', function(data) {
this.addToHistory(c.peer, data);
this.sendIReceived(c.peer, data);
}.bind(this));
c.on('close', function() {
console.log(c.peer + ' has left the chat.');
delete this._connectedPeers[peer];
}.bind(this));
if(!this.peers){
this.set('peers',[]);
}
var peerInContacts = this.peers.some(function(p) {
return p.peer === peer;
});
if (!peerInContacts) {
this.push('peers', {
peer: peer
});
}
this._connectedPeers[peer] = 1;
this.fire('connected-to-peer', peer);
}
if (c.label === 'file') {
c.on('data', function(data) {
// If we're getting a file, create a URL for it.
console.log('received!', data);
this.fire('file-received', {
peer: peer,
url: data.url,
name: data.name,
});
}.bind(this));
}
if (c.label === 'received-channel') {
c.on('data', function(data) {
this._peerReceivedMsg(c.peer, data);
}.bind(this));
}
//send unsend messages
if (this._unsendMsgs[peer]) {
this._unsendMsgs[peer].forEach(function(msg) {
this.send(peer, msg);
}.bind(this));
}
},
connectToPeer: (function() {
function request(requestedPeer) {
return function() {
var c = this._peer.connect(requestedPeer, {
label: 'chat',
metadata: {
message: 'hi i want to chat with you!'
}
});
c.on('open', function() {
this.connect(c);
}.bind(this));
var c1 = this._peer.connect(requestedPeer, {
label: 'received-channel',
});
c1.on('open', function() {
this.connect(c1);
}.bind(this));
var f = this._peer.connect(requestedPeer, {
label: 'file',
reliable: true
});
f.on('open', function() {
this.connect(f);
}.bind(this));
f.on('error', function(err) {
console.log(err);
});
};
}
return function(requestedPeer) {
if (!this._connectedPeers[requestedPeer]) {
this.set('peer', 'loading');
if (this._peerOpen) {
request(requestedPeer).bind(this)();
} else {
this._initCallbacks.push(request(requestedPeer).bind(this));
}
}
};
}()),
send: function(peerId, msg) {
var conns = this._peer.connections[peerId];
if (conns) {
for (var i = 0; i < conns.length; i++) {
var conn = conns[i];
if (conn.label === 'chat') {
this._addToUnsendMsgs(peerId, msg);
conn.send(msg);
this.addToHistory(conn.peer, msg);
}
}
} else {
this._addToUnsendMsgs(peerId, msg);
this.connectToPeer(peerId);
}
},
sendFile: function(peerId, file) {
var conns = this._peer.connections[peerId];
if (conns) {
for (var i = 0; i < conns.length; i++) {
var conn = conns[i];
if (conn.label === 'file') {
conn.send(file);
console.log('file send');
}
}
}
},
_addToUnsendMsgs: function(peerId, msg) {
if (!this._unsendMsgs[peerId]) {
this._unsendMsgs[peerId] = [];
}
if (this._unsendMsgs[peerId].indexOf(msg) === -1) {
this._unsendMsgs[peerId].push(msg);
console.log('added unsend', msg);
}
},
sendIReceived: function(peerId, msg) {
var conns = this._peer.connections[peerId];
if (conns) {
for (var i = 0; i < conns.length; i++) {
var conn = conns[i];
if (conn.label === 'received-channel') {
conn.send(msg);
}
}
} else {
this.connectToPeer(peerId);
}
},
addToHistory: function(peerId, msg) {
console.log('send message', msg);
this.fire('new-message', msg);
},
initializeDefaultPeers: function() {
this.peers = [];
},
_peerReceivedMsg: function(peerId, msg) {
console.log('received', peerId, msg);
var i = this._unsendMsgs[peerId].indexOf(msg);
this._unsendMsgs[peerId].splice(i, 1);
}
});
</script>
</dom-module>