Create new rooms

This commit is contained in:
Michael Zhang 2020-11-27 00:36:02 -06:00
parent 815d78d1fb
commit 50f359c1c3
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
19 changed files with 93 additions and 224 deletions

View file

@ -1,3 +0,0 @@
import { Mongo } from 'meteor/mongo';
export default new Mongo.Collection('links');

View file

@ -1,24 +0,0 @@
// Tests for the behavior of the links collection
//
// https://guide.meteor.com/testing.html
import { Meteor } from 'meteor/meteor';
import { assert } from 'chai';
import Links from './Links.js';
if (Meteor.isServer) {
describe('links collection', function () {
it('insert correctly', function () {
const linkId = Links.insert({
title: 'meteor homepage',
url: 'https://www.meteor.com',
});
const added = Links.find({ _id: linkId });
const collectionName = added._getCollectionName();
const count = added.count();
assert.equal(collectionName, 'links');
assert.equal(count, 1);
});
});
}

View file

@ -0,0 +1,8 @@
import { Mongo } from "meteor/mongo";
let Players = new Mongo.Collection("players");
// let collection = Players.rawCollection();
// collection.ensureIndex({ joinCode: 1 }, { unique: true });
export default Players;

View file

@ -1,3 +1,8 @@
import { Mongo } from "meteor/mongo";
export default new Mongo.Collection("rooms");
let Rooms = new Mongo.Collection("rooms");
let collection = Rooms.rawCollection();
collection.ensureIndex({ joinCode: 1 }, { unique: true });
export default Rooms;

View file

@ -1,32 +1,4 @@
import { Meteor } from 'meteor/meteor';
import Links from './collections/Links.js';
Meteor.startup(() => {
// if the Links collection is empty
if (Links.find().count() === 0) {
const data = [
{
title: 'Do the Tutorial',
url: 'https://www.meteor.com/try',
createdAt: new Date(),
},
{
title: 'Follow the Guide',
url: 'http://guide.meteor.com',
createdAt: new Date(),
},
{
title: 'Read the Docs',
url: 'https://docs.meteor.com',
createdAt: new Date(),
},
{
title: 'Discussions',
url: 'https://forums.meteor.com',
createdAt: new Date(),
},
];
data.forEach(link => Links.insert(link));
}
});

View file

@ -1,16 +0,0 @@
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import Links from '../collections/Links.js';
Meteor.methods({
'createLink'(title, url) {
check(url, String);
check(title, String);
return Links.insert({
url,
title,
createdAt: new Date(),
});
},
});

View file

@ -1,20 +0,0 @@
import { Meteor } from 'meteor/meteor';
import { assert } from 'chai';
import Links from '../collections/Links.js';
import './methods.js';
if (Meteor.isServer) {
describe('method: createLink', function () {
beforeEach(function () {
Links.remove({});
});
it('can add a new link', function () {
const addLink = Meteor.server.method_handlers['createLink'];
addLink.apply({}, ['meteor.com', 'https://www.meteor.com']);
assert.equal(Links.find().count(), 1);
});
});
}

View file

@ -1,9 +1,40 @@
import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import { Meteor } from "meteor/meteor";
import { Random } from "meteor/random";
import { check } from "meteor/check";
import Rooms from "../collections/Rooms.js";
import Players from "../collections/Players.js";
Meteor.methods({
"newGame"({ name }) {
"newGame": async ({ name }) => {
check(name, String);
console.log("name", name);
let roomId = null;
let state = "waitingRoom";
// attempt to get a valid room code 10 times
let remainingAttempts = 10;
let joinCode;
while (roomId === null && remainingAttempts > 0) {
joinCode = Random.hexString(6);
let started = new Date();
try {
let result = Rooms.insert({ joinCode, started, state });
roomId = result;
break;
} catch (e) {
// BulkWriteError
if (e.code === 11000) {
remainingAttempts -= 1;
}
}
}
let playerId = Players.insert({ roomId, name });
if (remainingAttempts == 0 && roomId === null) {
return "failed";
}
return { playerId, roomId, joinCode };
},
});

View file

@ -1 +1 @@
import './links'
// import './links'

View file

@ -1,6 +0,0 @@
import { Meteor } from 'meteor/meteor';
import Links from '../collections/Links.js';
Meteor.publish('links', function () {
return Links.find();
});

View file

@ -1,22 +0,0 @@
import { assert } from 'chai'
import { PublicationCollector } from 'meteor/johanbrook:publication-collector'
import Links from '../collections/Links.js'
import './publications.js'
describe('Publish links', function () {
beforeEach(function () {
Links.remove({})
Links.insert({
title: 'meteor homepage',
url: 'https://www.meteor.com'
})
})
it('sends all links', function (done) {
const collector = new PublicationCollector()
collector.collect('links', (collections) => {
assert.equal(collections.links.length, 1)
done()
})
})
})

View file

@ -5,14 +5,10 @@
</template>
<script>
import Hello from './components/Hello.vue'
import Info from './components/Info.vue'
import Lobby from './components/Lobby.vue'
export default {
components: {
Hello,
Info,
Lobby,
},
@ -26,8 +22,8 @@ export default {
</script>
<style>
body {
font-family: sans-serif;
padding: 10px;
}
body {
font-family: sans-serif;
padding: 10px;
}
</style>

View file

@ -1,27 +0,0 @@
<template>
<div>
<button @click="increment">Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
</div>
</template>
<script>
export default {
data() {
return {
counter: 0,
}
},
methods: {
increment() {
this.counter += 1
}
},
}
</script>
<style scoped>
p {
font-family: serif;
}
</style>

View file

@ -1,55 +0,0 @@
<template>
<div>
<h2>Learn Meteor!</h2>
<ul>
<li>
<form class="info-link-add">
<input type="text" v-model="title" name="title" placeholder="Title" required>
<input type="url" v-model="url" name="url" placeholder="Url" required>
<input type="submit" name="submit" @click="submit($event)" value="Add new link">
</form>
</li>
<li v-for="link in links"><a :href="link.url" target="_blank">{{link.title}}</a></li>
</ul>
</div>
</template>
<script>
import Links from '../../api/collections/Links'
export default {
data() {
return {
title: "",
url: "",
}
},
meteor: {
$subscribe: {
'links': [],
},
links () {
return Links.find({})
},
},
methods: {
submit(event) {
event.preventDefault()
Meteor.call('createLink', this.title, this.url, (error) => {
if (error) {
alert(error.error)
} else {
this.title = ''
this.url = ''
}
})
}
},
}
</script>
<style scoped>
ul {
font-family: monospace;
}
</style>

View file

@ -3,8 +3,15 @@
<h1>LOBBY</h1>
<form v-on:submit.prevent="newGame">
<input type="text" autocomplete="off" v-model="newGameName" required placeholder="what's your name?" />
<button id="newgame-btn">new game</button>
<input
type="text"
autocomplete="off"
required
placeholder="what's your name?"
v-model="newGameName"
:disabled="loading"
/>
<button type="submit">new game</button>
</form>
<p>or</p>
@ -23,15 +30,18 @@ export default {
data() {
return {
loading: false,
newGameName: "",
};
},
methods: {
newGame: (evt) => {
newGame: function (evt) {
loading = true;
let name = this.newGameName;
console.log("name", name);
Meteor.call("newGame", { name });
Meteor.call("newGame", { name }, (err, res) => {
console.log(err, res);
});
}
}
}

View file

@ -0,0 +1,12 @@
<template>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>

View file

@ -1,4 +1,6 @@
import Vue from 'vue'
import VueMeteorTracker from 'vue-meteor-tracker'
import Vue from "vue";
import Vuex from "vuex";
import VueMeteorTracker from "vue-meteor-tracker";
Vue.use(VueMeteorTracker)
Vue.use(VueMeteorTracker);
Vue.use(Vuex);

5
package-lock.json generated
View file

@ -594,6 +594,11 @@
"requires": {
"lodash.omit": "^4.5.0"
}
},
"vuex": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.0.tgz",
"integrity": "sha512-W74OO2vCJPs9/YjNjW8lLbj+jzT24waTo2KShI8jLvJW8OaIkgb3wuAMA7D+ZiUxDOx3ubwSZTaJBip9G8a3aQ=="
}
}
}

View file

@ -11,7 +11,8 @@
"@babel/runtime": "^7.11.2",
"meteor-node-stubs": "^1.0.1",
"vue": "^2.6.12",
"vue-meteor-tracker": "^2.0.0-beta.5"
"vue-meteor-tracker": "^2.0.0-beta.5",
"vuex": "^3.6.0"
},
"meteor": {
"mainModule": {