Browse Source

Initial Coursera code added, code from w4 removed.

Frederic G. MARAND 9 years ago
parent
commit
40f0c22c0f

+ 1 - 4
.eslintrc.js

@@ -26,12 +26,9 @@ module.exports = {
     "Router": true,
 
     // aldeed:autoform
-    SimpleSchema: true,
+    SimpleSchema: true
 
     // Project-specific.
-    "Documents": true,
-    "EditingUsers": true,
-    "Comments": true
   },
 
   "plugins": ["react"],

+ 1 - 1
.meteor/.id

@@ -4,4 +4,4 @@
 #   - ensuring you don't accidentally deploy one app on top of another
 #   - providing package authors with aggregated statistics
 
-jxlv0l1d0dnlx1bhdvqs
+17g5jj8l610yy1aerkcr

+ 16 - 21
.meteor/packages

@@ -4,26 +4,21 @@
 # 'meteor add' and 'meteor remove' will edit this file for you,
 # but you can also edit it by hand.
 
-mizzao:sharejs-codemirror
-twbs:bootstrap
-standard-minifiers
-meteor-base
-mobile-experience
-mongo
-blaze-html-templates
-session
-jquery
-tracker
-logging
-reload
-random
-ejson
-spacebars
-check
-ecmascript
+meteor-base             # Packages every Meteor app needs to have
+mobile-experience       # Packages for a great mobile UX
+mongo                   # The database Meteor supports right now
+blaze-html-templates    # Compile .html files into Meteor Blaze views
+session                 # Client-side reactive dictionary for your app
+jquery                  # Helpful client-side library
+tracker                 # Meteor's client-side reactive programming library
+
+standard-minifiers      # JS/CSS minifiers run for production mode
+es5-shim                # ECMAScript 5 compatibility for older browsers.
+ecmascript              # Enable ECMAScript2015+ syntax in app code
+
+autopublish             # Publish all data to the clients (for prototyping)
+iron:router
 accounts-password
+twbs:bootstrap
 ian:accounts-ui-bootstrap-3
-babrahams:editable-text
-iron:router
-aldeed:autoform
-aldeed:collection2
+insecure

+ 5 - 16
.meteor/versions

@@ -1,13 +1,10 @@
 accounts-base@1.2.2
 accounts-password@1.1.4
-aldeed:autoform@5.8.1
-aldeed:collection2@2.3.1
-aldeed:simple-schema@1.1.0
 anti:i18n@0.4.3
+autopublish@1.0.4
 autoupdate@1.2.4
 babel-compiler@5.8.24_1
 babel-runtime@0.1.4
-babrahams:editable-text@0.8.10
 base64@1.0.4
 binary-heap@1.0.4
 blaze@2.1.3
@@ -18,8 +15,6 @@ caching-compiler@1.0.0
 caching-html-compiler@1.0.2
 callback-hook@1.0.4
 check@1.1.0
-coffeescript@1.0.11
-dburles:mongo-collection-instances@0.3.4
 ddp@1.2.2
 ddp-client@1.2.1
 ddp-common@1.2.2
@@ -27,21 +22,20 @@ ddp-rate-limiter@1.0.0
 ddp-server@1.2.2
 deps@1.0.9
 diff-sequence@1.0.1
-djedi:sanitize-html@1.11.2
 ecmascript@0.1.6
 ecmascript-runtime@0.2.6
 ejson@1.0.7
 email@1.0.8
+es5-shim@4.1.14
 fastclick@1.0.7
 geojson-utils@1.0.4
-gwendall:body-events@0.1.6
-handlebars@1.0.4
 hot-code-push@1.0.0
 html-tools@1.0.5
 htmljs@1.0.5
 http@1.1.1
-ian:accounts-ui-bootstrap-3@1.2.89
+ian:accounts-ui-bootstrap-3@1.2.83
 id-map@1.0.4
+insecure@1.0.4
 iron:controller@1.0.12
 iron:core@1.0.11
 iron:dynamic-template@1.0.12
@@ -51,7 +45,6 @@ iron:middleware-stack@1.0.11
 iron:router@1.0.12
 iron:url@1.0.11
 jquery@1.11.4
-lai:collection-extensions@0.1.4
 launch-screen@1.0.4
 livedata@1.0.15
 localstorage@1.0.5
@@ -60,14 +53,10 @@ meteor@1.1.10
 meteor-base@1.0.1
 minifiers@1.1.7
 minimongo@1.0.10
-mizzao:sharejs@0.7.5
-mizzao:sharejs-codemirror@4.12.0
 mobile-experience@1.0.1
 mobile-status-bar@1.0.6
-momentjs:moment@2.10.6
 mongo@1.1.3
 mongo-id@1.0.1
-mongo-livedata@1.0.9
 npm-bcrypt@0.7.8_2
 npm-mongo@1.4.39_1
 observe-sequence@1.0.7
@@ -91,7 +80,7 @@ stylus@2.511.1
 templating@1.1.5
 templating-tools@1.0.0
 tracker@1.0.9
-twbs:bootstrap@3.3.6
+twbs:bootstrap@3.3.5
 ui@1.0.8
 underscore@1.0.4
 url@1.0.5

+ 0 - 86
client/accounts.js

@@ -1,86 +0,0 @@
-// configure the special accounts user interface
-// by setting up some extra fields and specifying constraints
-// see:https://github.com/ianmartorell/meteor-accounts-ui-bootstrap-3/
-Accounts.ui.config({
-  requestPermissions: {},
-  extraSignupFields: [
-    {
-      fieldName: "first-name",
-      fieldLabel: "First name",
-      inputType: "text",
-      visible: true,
-      validate: function (value, errorFunction) {
-        if (!value) {
-          errorFunction("Please write your first name");
-          return false;
-        }
-        else {
-          return true;
-        }
-      }
-    },
-    {
-      fieldName: "last-name",
-      fieldLabel: "Last name",
-      inputType: "text",
-      visible: true
-    },
-    {
-      fieldName: "gender",
-      showFieldLabel: false,      // If true, fieldLabel will be shown before radio group
-      fieldLabel: "Gender",
-      inputType: "radio",
-      radioLayout: "vertical",    // It can be "inline" or "vertical"
-      data: [
-        {                    // Array of radio options, all properties are required
-          id: 1,                  // id suffix of the radio element
-          label: "Male",          // label for the radio element
-          value: "m"              // value of the radio element, this will be saved.
-        },
-        {
-          id: 2,
-          label: "Female",
-          value: "f",
-          checked: "checked"
-        }
-      ],
-      visible: true
-    },
-    {
-      fieldName: "country",
-      fieldLabel: "Country",
-      inputType: "select",
-      showFieldLabel: true,
-      empty: "Please select your country of residence",
-      data: [
-        {
-          id: 1,
-          label: "United States",
-          value: "us"
-        },
-        {
-          id: 2,
-          label: "Spain",
-          value: "es"
-        }
-      ],
-      visible: true
-    },
-    {
-      fieldName: "terms",
-      fieldLabel: "I accept the terms and conditions <a href=\"\">Some outrageous terms</a>",
-      inputType: "checkbox",
-      visible: true,
-      saveToProfile: false,
-      validate: function (value, errorFunction) {
-        if (value) {
-          return true;
-        }
-        else {
-          errorFunction("You must accept the terms and conditions.");
-          return false;
-        }
-      }
-    }
-  ]
-});

+ 0 - 85
client/docItem.html

@@ -1,85 +0,0 @@
-<template name="docItem">
-  <div class="container top-margin">
-    <div class="row">
-      <div class="col-md-12">
-        {{> docMeta }}
-      </div>
-    </div>
-    <div class="row">
-      <div class="col-md-12">
-        {{> editingUsers }}
-      </div>
-    </div>
-    <div class="row">
-      <div class="col-md-6">
-        {{> editor}}
-      </div>
-      <div class="col-md-6">
-        {{> viewer }}
-      </div>
-    </div>
-
-    {{> commentList }}
-
-    {{> insertCommentForm }}
-  </div><!-- end of docItem container -->
-
-</template>
-
-<template name="editor">
-  <h2>doc id: {{ docid }}</h2>
-  {{> sharejsCM docid=docid onRender=config id="editor" mode="javascript" }}
-</template>
-
-<template name="viewer">
-  <iframe id="viewer_iframe">
-  </iframe>
-</template>
-
-<template name="docMeta">
-  {{#with document }}
-    <span class="h1">{{> editableText collection="documents" field="title" }}</span>
-    {{#if canEdit }}
-      <div class="checkbox">
-        <label>
-          <input type="checkbox" class="js-tog-private" checked="{{ isPrivate }}"/>Private
-        </label>
-      </div>
-    {{/if}}
-  {{/with}}
-</template>
-
-<template name="editingUsers">
-  Editors:
-  {{#each users }}
-    <span class="label label-success">{{firstname}}</span>
-
-  {{/each}}
-</template>
-
-<template name="commentList">
-  <ul>
-    {{#each comments }}
-      <li>{{ title }}
-        <p>{{ body }}</p>
-      </li>
-    {{/each}}
-  </ul>
-</template>
-
-<template name="insertCommentForm2">
-  {{> quickForm collection="Comments" id="insertCommentForm" type="method" meteormethod="addComment" }}
-</template>
-
-<template name="insertCommentForm">
-  {{#autoForm collection="Comments" id="insertCommentForm" type="method" meteormethod="addComment" }}
-    <fieldset>
-      <legend>Comment</legend>
-      {{> afQuickField name="title" }}
-      {{> afQuickField name="body" rows=6 value="starter text" }}
-      {{> afQuickField name="docid" value=docid type="hidden" }}
-      {{> afQuickField name="owner" value="invalid" type="hidden" }}
-    </fieldset>
-    <button type="submit" class="btn btn-primary">Insert</button>
-  {{/autoForm}}
-</template>

+ 0 - 13
client/docList.html

@@ -1,13 +0,0 @@
-<template name="docList">
-  <div class="container top-margin">
-    <div class="row">
-      {{#each documents }}
-        <div class="col-md-3 col-xs-6">
-          <div class="light-border">
-            <a href="/documents/{{ _id }}">{{ title }}</a>
-          </div>
-        </div>
-      {{/each}}
-    </div>
-  </div>
-</template>

+ 0 - 191
client/main.js

@@ -1,191 +0,0 @@
-// code that is only sent to the client
-// main.js is loaded last:
-// http://docs.meteor.com/#/full/structuringyourapp
-
-// subscribe to read data
-Meteor.subscribe("documents");
-Meteor.subscribe("editingUsers");
-Meteor.subscribe("comments");
-
-Router.configure({
-  layoutTemplate: "ApplicationLayout"
-});
-
-Router.route("/", function () {
-  Meteor._debug("Routing /");
-  this.render("navbar", { to: "header" });
-  this.render("docList", { to: "main" });
-});
-Router.route("/documents/:_id", function () {
-  Meteor._debug("Routing /documents/" + this.params._id);
-  Session.set("docid", this.params._id);
-  this.render("navbar", { to: "header" });
-  this.render("docItem", { to: "main" });
-});
-
-
-Template.editor.helpers({
-  // Return the id of the first document you can find.
-  docid: function () {
-    setupCurrentDocument();
-    return Session.get("docid");
-  },
-  // Configure the CodeMirror editor.
-  config: function () {
-    return function (editor) {
-      editor.setOption("lineNumbers", true);
-      editor.setOption("theme", "cobalt");
-      editor.setOption("mode", "html");
-      // Set a callback that gets triggered whenever the user
-      // makes a change in the code editing window.
-      editor.on("change", function (cmEditor /* , info */) {
-        let $preview = $("#viewer_iframe");
-        // Send the current code over to the iframe for rendering.
-        $preview.contents().find("html").html(cmEditor.getValue());
-        Meteor.call("addEditingUser", Session.get("docid"));
-      });
-    };
-  }
-});
-
-Template.editingUsers.helpers({
-  // Retrieve a list of users that are editing this document.
-  users: function () {
-    let doc = Documents.findOne({ _id: Session.get("docid") });
-    if (!doc) {
-      // Give up.
-      return null;
-    }
-    let eUsers = EditingUsers.findOne({ docId: doc._id });
-    if (!eUsers) {
-      // Give up.
-      return null;
-    }
-    let users = new Array();
-    let i = 0;
-    for (let userId in eUsers.users) {
-      users[i] = fixObjectsKeys(eUsers.users[userId]);
-      users[i]._id = userId;
-      i++;
-    }
-    return users;
-  }
-});
-
-Template.navbar.helpers({
-  // Retrieve a list of documents.
-  documents: function () {
-    return Documents.find();
-  }
-});
-
-Template.docList.helpers({
-  // Retrieve a list of documents.
-  documents: function () {
-    return Documents.find();
-  }
-});
-
-Template.insertCommentForm.helpers({
-  docid: function () {
-    return Session.get("docid");
-  }
-});
-
-Template.commentList.helpers({
-  comments: function () {
-    return Comments.find({ docid: Session.get("docid") });
-  }
-});
-
-Template.docMeta.helpers({
-  // Find current document.
-  document: function () {
-    return Documents.findOne({ _id: Session.get("docid") });
-  },
-  // Test if a user is allowed to edit current doc.
-  canEdit: function () {
-    let doc = Documents.findOne({ _id: Session.get("docid") });
-    return doc && doc.owner === Meteor.userId();
-  },
-  isPrivate: function () {
-    let doc = Documents.findOne({ _id: Session.get("docid") });
-    return !!(doc.isPrivate);
-  }
-});
-
-Template.editableText.helpers({
-  // Test if a user is allowed to edit current doc.
-  userCanEdit: function (doc, collection) {
-    Meteor._debug("userCanEdit", doc, collection);
-    // Can edit if the document is owned by me.
-    doc = Documents.findOne({
-      _id: Session.get("docid"),
-      owner: Meteor.userId()
-    });
-    return !!doc;
-  }
-});
-
-Template.navbar.events({
-  // Add doc button.
-  "click .js-add-doc": function (event) {
-    event.preventDefault();
-    // User not available.
-    if (!Meteor.user()) {
-      alert("You need to login first!");
-    }
-    else {
-      // They are logged in... lets insert a doc.
-      Meteor.call("addDoc", function (err, res) {
-        if (!err) {
-          console.log("addDoc res", res);
-          Session.set("docid", res);
-        }
-      });
-    }
-  },
-
-  // Load doc button.
-  "click .js-load-doc": function (event) {
-    // This contains a complete document.
-    Session.set("docid", this._id);
-  }
-});
-
-Template.docMeta.events({
-  // Change document privacy.
-  "click .js-tog-private": function (event) {
-    // They are logged in... lets insert a doc.
-    const docid = Session.get("docid");
-    if (docid) {
-      const doc = { _id: docid, isPrivate: event.target.checked };
-      Meteor.call("updateDocPrivacy", doc);
-    }
-  }
-});
-
-// Helper to make sure a doc is available.
-function setupCurrentDocument() {
-  let doc;
-  // No docid set yet.
-  if (!Session.get("docid")) {
-    doc = Documents.findOne();
-    if (doc) {
-      Session.set("docid", doc._id);
-    }
-  }
-}
-
-// This renames object keys by removing hyphens to make them compatible
-// with spacebars.
-function fixObjectsKeys(obj) {
-  let newObj = {};
-  for (let key in obj) {
-    if (obj.hasOwnProperty(key)) {
-      const key2 = key.replace("-", "");
-      newObj[key2] = obj[key];
-    }
-  }
-  return newObj;
-}

+ 0 - 31
client/navbar.html

@@ -1,31 +0,0 @@
-<template name="navbar">
-  <nav class="navbar navbar-default navbar-fixed-top">
-    <div class="container">
-      <a class="navbar-brand" href="/">TextCircle</a><!-- nav title -->
-      <ul class="nav navbar-nav">
-        <li>
-          <a href="#" class="js-add-doc">
-            <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
-            New document
-          </a>
-        </li>
-        <!-- drop down list -->
-        <li role="presentation" class="dropdown">
-          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
-            Documents <span class="caret"></span>
-          </a>
-          <ul class="dropdown-menu">
-            {{#each documents }}
-              <li><a href="/documents/{{ _id }}">{{ title }}</a></li>
-            {{/each}}
-          </ul>
-        </li>
-        <!-- end drop down list -->
-      </ul>
-
-      <p class="navbar-text navbar-right">
-        {{> loginButtons align="right" }}
-      </p>
-    </div><!-- /nav container -->
-  </nav><!-- /nav -->
-</template>

+ 0 - 18
client/textcircle.css

@@ -1,18 +0,0 @@
-/* Workaround BS3 fixed navbar height
-body {
-  padding-top: 70px;
-}
-*/
-.top-margin {
-  margin-top: 50px; }
-
-#viewer_iframe {
-  border: 1px solid gray;
-  resize: both;
-  width: 100%; }
-
-.light-border {
-  border: 1px solid gray;
-  width: 100%; }
-
-/*# sourceMappingURL=textcircle.css.map */

+ 0 - 8
client/textcircle.html

@@ -1,8 +0,0 @@
-<template name="ApplicationLayout">
-  <head>
-    <title>textcircle</title>
-  </head>
-
-  {{> yield "header" }}
-  {{> yield "main" }}
-</template>

+ 0 - 22
client/textcircle.scss

@@ -1,22 +0,0 @@
-/* Workaround BS3 fixed navbar height
-body {
-  padding-top: 70px;
-}
-*/
-
-$topMargin: 50px;
-
-.top-margin {
-  margin-top: $topMargin;
-}
-
-#viewer_iframe {
-  border: 1px solid gray;
-  resize: both;
-  width: 100%;
-}
-
-.light-border {
-  border: 1px solid gray;
-  width: 100%;
-}

+ 0 - 25
client/theme/cobalt.css

@@ -1,25 +0,0 @@
-.cm-s-cobalt.CodeMirror { background: #002240; color: white; }
-.cm-s-cobalt div.CodeMirror-selected { background: #b36539; }
-.cm-s-cobalt .CodeMirror-line::selection, .cm-s-cobalt .CodeMirror-line > span::selection, .cm-s-cobalt .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); }
-.cm-s-cobalt .CodeMirror-line::-moz-selection, .cm-s-cobalt .CodeMirror-line > span::-moz-selection, .cm-s-cobalt .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); }
-.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
-.cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; }
-.cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
-.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; }
-.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-cobalt span.cm-comment { color: #08f; }
-.cm-s-cobalt span.cm-atom { color: #845dc4; }
-.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
-.cm-s-cobalt span.cm-keyword { color: #ffee80; }
-.cm-s-cobalt span.cm-string { color: #3ad900; }
-.cm-s-cobalt span.cm-meta { color: #ff9d00; }
-.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
-.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def { color: white; }
-.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
-.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
-.cm-s-cobalt span.cm-link { color: #845dc4; }
-.cm-s-cobalt span.cm-error { color: #9d1e15; }
-
-.cm-s-cobalt .CodeMirror-activeline-background { background: #002D57; }
-.cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }

+ 0 - 26
lib/collections.js

@@ -1,26 +0,0 @@
-// This collection stores all the documents.
-// Note: not Documents, but this.Documents, because of the editing package (?)
-this.Documents = new Mongo.Collection("documents");
-
-// This collection stores sets of users that are editing documents.
-EditingUsers = new Mongo.Collection("editingUsers");
-
-Comments = new Mongo.Collection("comments");
-Comments.attachSchema(new SimpleSchema({
-  title: {
-    type: String,
-    label: "Title",
-    max: 200
-  },
-  body: {
-    type: String,
-    label: "Comment",
-    max: 1000
-  },
-  docid: {
-    type: String
-  },
-  owner: {
-    type: String
-  }
-}));

+ 10 - 0
minstant.css

@@ -0,0 +1,10 @@
+/* CSS declarations go here */
+
+.user_avatar{
+	min-height:100px;
+	text-align: center;
+
+}
+.avatar_img{
+	height:75px;
+}

+ 98 - 0
minstant.html

@@ -0,0 +1,98 @@
+<head>
+  <title>minstant</title>
+</head>
+
+<body>
+</body>
+
+<!-- this is the main template used by iron:router to build the page -->
+<template name="ApplicationLayout">
+	{{> yield "header"}}
+	
+	<div class="container">
+	{{> yield "main"}}
+	</div>
+</template>
+
+<!-- top level template for the nav bar -->
+<template name="navbar">
+<nav class="navbar navbar-default">
+  <div class="container-fluid">
+    <div class="navbar-header">
+      <a class="navbar-brand" href="/">
+        Minstant!
+      </a>
+    </div>
+    <div class="nav navbar-nav">
+    {{> loginButtons}}
+</div>
+  </div>
+</nav>
+</template>
+
+<!-- Top level template for the lobby page -->
+<template name="lobby_page">
+	{{> available_user_list}}
+</template>
+
+<!-- display a list of users -->
+<template name="available_user_list">
+	<h2>Choose someone to chat with:</h2>
+	<div class="row">
+	{{#each users}}
+	{{> available_user}}
+	{{/each}}
+</div>
+</template>
+
+<!-- display an individual user -->
+<template name="available_user">
+	<div class="col-md-2">
+		<div class="user_avatar">
+			{{#if isMyUser _id}} 
+			<div class="bg-success">{{getUsername _id}} (YOU)
+				<br/>
+				<img src="/{{profile.avatar}}" class="avatar_img">			
+			</div>
+			{{else}}
+			<a href="/chat/{{_id}}">
+				{{getUsername _id}}
+				<br/>
+				<img src="/{{profile.avatar}}" class="avatar_img">
+			</a>
+			{{/if}}
+		</div>
+	</div>
+</template>
+
+
+<!-- Top level template for the chat page -->
+<template name="chat_page">
+	<h2>Type in the box below to send a message!</h2>
+	<div class="row">
+		<div class="col-md-12">
+			<div class="well well-lg">
+			{{#each messages}}
+			{{> chat_message}}
+			{{/each}}
+			</div>	
+		</div>
+	</div>
+    <div class="row">
+		<div class="col-md-12">
+			<form class="js-send-chat">
+			<input class="input" type="text" name="chat" placeholder="type a message here...">
+			<button class="btn btn-default">send</button>
+		</form>
+		</div>
+	</div>
+</template>
+
+<!-- simple template that displays a message -->
+<template name="chat_message">
+	someone said: {{text}}
+	<br>
+</template>
+
+
+

+ 119 - 0
minstant.js

@@ -0,0 +1,119 @@
+Chats = new Mongo.Collection("chats");
+
+if (Meteor.isClient) {
+  // set up the main template the the router will use to build pages
+  Router.configure({
+    layoutTemplate: 'ApplicationLayout'
+  });
+  // specify the top level route, the page users see when they arrive at the site
+  Router.route('/', function () {
+    console.log("rendering root /");
+    this.render("navbar", {to:"header"});
+    this.render("lobby_page", {to:"main"});  
+  });
+
+  // specify a route that allows the current user to chat to another users
+  Router.route('/chat/:_id', function () {
+    // the user they want to chat to has id equal to 
+    // the id sent in after /chat/... 
+    var otherUserId = this.params._id;
+    // find a chat that has two users that match current user id
+    // and the requested user id
+    var filter = {$or:[
+                {user1Id:Meteor.userId(), user2Id:otherUserId}, 
+                {user2Id:Meteor.userId(), user1Id:otherUserId}
+                ]};
+    var chat = Chats.findOne(filter);
+    if (!chat){// no chat matching the filter - need to insert a new one
+      chatId = Chats.insert({user1Id:Meteor.userId(), user2Id:otherUserId});
+    }
+    else {// there is a chat going already - use that. 
+      chatId = chat._id;
+    }
+    if (chatId){// looking good, save the id to the session
+      Session.set("chatId",chatId);
+    }
+    this.render("navbar", {to:"header"});
+    this.render("chat_page", {to:"main"});  
+  });
+
+  ///
+  // helper functions 
+  /// 
+  Template.available_user_list.helpers({
+    users:function(){
+      return Meteor.users.find();
+    }
+  })
+ Template.available_user.helpers({
+    getUsername:function(userId){
+      user = Meteor.users.findOne({_id:userId});
+      return user.profile.username;
+    }, 
+    isMyUser:function(userId){
+      if (userId == Meteor.userId()){
+        return true;
+      }
+      else {
+        return false;
+      }
+    }
+  })
+
+
+  Template.chat_page.helpers({
+    messages:function(){
+      var chat = Chats.findOne({_id:Session.get("chatId")});
+      return chat.messages;
+    }, 
+    other_user:function(){
+      return ""
+    }, 
+
+  })
+ Template.chat_page.events({
+  // this event fires when the user sends a message on the chat page
+  'submit .js-send-chat':function(event){
+    // stop the form from triggering a page reload
+    event.preventDefault();
+    // see if we can find a chat object in the database
+    // to which we'll add the message
+    var chat = Chats.findOne({_id:Session.get("chatId")});
+    if (chat){// ok - we have a chat to use
+      var msgs = chat.messages; // pull the messages property
+      if (!msgs){// no messages yet, create a new array
+        msgs = [];
+      }
+      // is a good idea to insert data straight from the form
+      // (i.e. the user) into the database?? certainly not. 
+      // push adds the message to the end of the array
+      msgs.push({text: event.target.chat.value});
+      // reset the form
+      event.target.chat.value = "";
+      // put the messages array onto the chat object
+      chat.messages = msgs;
+      // update the chat object in the database.
+      Chats.update(chat._id, chat);
+    }
+  }
+ })
+}
+
+
+// start up script that creates some users for testing
+// users have the username 'user1@test.com' .. 'user8@test.com'
+// and the password test123 
+
+if (Meteor.isServer) {
+  Meteor.startup(function () {
+    if (!Meteor.users.findOne()){
+      for (var i=1;i<9;i++){
+        var email = "user"+i+"@test.com";
+        var username = "user"+i;
+        var avatar = "ava"+i+".png"
+        console.log("creating a user with password 'test123' and username/ email: "+email);
+        Meteor.users.insert({profile:{username:username, avatar:avatar}, emails:[{address:email}],services:{ password:{"bcrypt" : "$2a$10$I3erQ084OiyILTv8ybtQ4ON6wusgPbMZ6.P33zzSDei.BbDL.Q4EO"}}});
+      }
+    } 
+  });
+}

BIN
public/ava1.png


BIN
public/ava2.png


BIN
public/ava3.png


BIN
public/ava4.png


BIN
public/ava5.png


BIN
public/ava6.png


BIN
public/ava7.png


BIN
public/ava8.png


+ 0 - 40
public/bootstrap_cheat.txt

@@ -1,40 +0,0 @@
-================================================================================
-Navbar fixed at top
--------------------
-
-  HTML
-  ----
-
-  <nav class="navbar navbar-default navbar-fixed-top">
-    <div class="container">
-      ...
-    </div>
-  </nav>
-
-  CSS
-  ---
-
-  body {
-    padding-top: 70px; /* Default navbar height: 50px */
-  }
-
-================================================================================
-
-Navbar fixed at bottom
-----------------------
-
-  HTML
-  ----
-
-  <nav class="navbar navbar-default navbar-fixed-bottom">
-    <div class="container">
-      ...
-    </div>
-  </nav>
-
-  CSS
-  ---
-
-  body {
-    padding-bottom: 70px;  /* Default navbar height: 50px */
-  }

+ 0 - 35
server/main.js

@@ -1,35 +0,0 @@
-// Code that is only sent to the server.
-
-// main.js is loaded last:
-// http://docs.meteor.com/#/full/structuringyourapp
-
-Meteor.startup(function () {
-  // Insert a document if there isn't one already.
-  if (!Documents.findOne()) {
-    Documents.insert({ title: "my new document" });
-  }
-});
-
-// Publish read access to collections.
-
-// All visible docs.
-Meteor.publish("documents", function () {
-  Meteor._debug("Publishing documents");
-  return Documents.find({
-    $or: [
-      { isPrivate: { $ne: true } },
-      { owner: this.userId }
-    ]
-  });
-});
-
-// Users editing docs.
-Meteor.publish("editingUsers", function () {
-  Meteor._debug("Publishing all editingUsers");
-  return EditingUsers.find();
-});
-
-Meteor.publish("comments", function () {
-  Meteor._debug("Publishing comments");
-  return Comments.find();
-});

+ 0 - 75
shared/main.js

@@ -1,75 +0,0 @@
-// Code that is shared between client and server, i.e. sent to both.
-
-// main.js is loaded last:
-// http://docs.meteor.com/#/full/structuringyourapp
-
-// Methods that provide write access to the data.
-Meteor.methods({
-  addComment: function (comment) {
-    Meteor._debug("addComment method running", comment);
-    // We are connected.
-    if (this.userId) {
-      //comment.createdOn = new Date();
-      comment.owner = this.userId;
-      const cid = Comments.insert(comment);
-      Meteor._debug("Comment id after insert", cid);
-      return cid;
-    }
-    return null;
-  },
-
-  addDoc: function () {
-    Meteor._debug("addDoc, this", this);
-    // Not logged-in.
-    if (!this.userId) {
-      return;
-    }
-    else {
-      let doc = {
-        owner: this.userId,
-        createdOn: new Date(),
-        title: "my new doc"
-      };
-      const docid = Documents.insert(doc);
-      return docid;
-    }
-  },
-
-  // Changing doc privacy settings.
-  updateDocPrivacy: function (doc) {
-    Meteor._debug("updatedocPrivacy", this.userId, doc)
-    if (!this.userId) {
-      return;
-    }
-    let res = Documents.update({ _id: doc._id, owner: this.userId }, { $set: { isPrivate: doc.isPrivate } });
-    Meteor._debug("update", res);
-  },
-
-  // Adding editors to a document.
-  addEditingUser: function (docid) {
-    let doc = Documents.findOne({ _id: docid });
-    if (!doc) {
-      // No doc: give up.
-      return;
-    }
-    if (!this.userId) {
-      // No logged-in user: give up.
-      return;
-    }
-    // Now I have a doc and possibly a user.
-    let user = Meteor.user().profile;
-    let eUsers = EditingUsers.findOne({ docId: doc._id });
-    // No editing users have been stored yet.
-    if (!eUsers) {
-      eUsers = {
-        docId: doc._id,
-        users: {}
-      };
-    }
-    user.lastEdit = new Date();
-    eUsers.users[this.userId] = user;
-
-    // Upsert: insert or update if filter matches.
-    EditingUsers.upsert({ _id: eUsers._id }, eUsers);
-  }
-});

+ 0 - 7
textcircle.css.map

@@ -1,7 +0,0 @@
-{
-"version": 3,
-"mappings": "AAAA;;;;EAIE;AAIF,WAAY;EACV,UAAU,EAHA,IAAI;;AAMhB,cAAe;EACb,MAAM,EAAE,cAAc;EACtB,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI",
-"sources": ["textcircle.scss"],
-"names": [],
-"file": "textcircle.css"
-}