Git Product home page Git Product logo

ioweb2015's Introduction

Google I/O 2015 web app

Setup

Prerequisites

  • Go 1.4.

  • Optional: gcloud tool and app component to run and deploy GAE-based backend (hint: gcloud components update app).

    Once gcloud and app component are installed, you'll need to do a one-off configuration by executing the following command: gcloud config set project <project-id>. Project ID can be any non-empty string if you just want to run the app locally.

Setup

  1. git clone https://github.com/GoogleChrome/ioweb2015.git
  2. cd ioweb2015
  3. npm install
  4. gulp setup

If you plan on modifying source code, be a good citizen and:

  1. Install EditorConfig plugin for your favourite browser. The plugin should automatically pick up the .editorconfig settings.
  2. Obey the pre-commit hook that's installed as part of gulp setup. It will check for JavaScript and code style errors before committing to the master branch.

Running

Run gulp serve to start a standalone backend, while still enjoying live-reload. You'll need Go for that.

Normally the app is running in "dev" environment but you can change that by providing --env argument to the gulp task:

# run in dev mode, default:
gulp serve
# set app environment to production:
gulp serve --env prod
# or run as if we were in staging:
gulp serve --env stage

Not that this does not change the way the backend code is compiled or the front-end is built. It merely changes a variable values, which the app takes into account when rendering a page or responding to a request.

Running in stage or prod requires real credentials when accessing external services. You'll need to run a one-off gulp decrypt which will decrypt a service account private key.

You can also use GAE dev appserver by running gulp serve:gae. This is closer to what we're using in our webapp environment but a bit slower on startup. You'll need gcloud tool and app component to do this.

To change the app environment when using GAE SDK, provide --env argument:

# run in dev mode, default:
gulp serve:gae
# set app environment to production:
gulp serve:gae --env prod
# or run as if we were in staging:
gulp serve:gae --env stage

Other arguments are:

  • --no-watch don't watch for file changes and recompile relative bits.
  • --open open serving url in a new browser tab on start.
  • --reload enable live reload. Always watches for file changes; --no-watch will have no effect.

Building

Run gulp. This will create dist directory with both front-end and backend parts, ready for deploy.

Note: Build won't succeed if either gulp jshint or gulp jscs reports errors.

You can also serve the build from dist by running gulp serve:dist, and navigating to http://localhost:8080.

serve:dist runs the app in prod mode by default. You can change that by providing the --env argument as with other serve tasks. For instance:

# run in stage instead of prod
gulp serve:dist --env stage

Deploying

To deploy complete application on App Engine:

  1. Run gulp which will build both frontend and backend in dist directory.
  2. Run gcloud preview app deploy dist/backend --version <v>.

The app will be deployed to the project configured in gcloud tool. To check which project you're deploying to, run gcloud config list and look for project = ... line.

Backend

Backend is written in Go. It can run on either Google App Engine or any other platform as a standalone binary program.

gulp backend will build a self-sufficient backend server and place the binary in backend/bin/server.

gulp backend:test will run backend server tests. If, while working on the backend, you feel tired of running the command again and again, use gulp backend:test --watch to watch for file changes and re-run tests automatically.

Add --gae cmd line argument to the test task to run GAE-based tests.

Debugging

A list of tools to help in a debugging process. NOT available in prod

Proxy with the service account credentials

http://HOST/io2015/debug/srvget?url=<some-url>

The backend will GET some-url and respond back with the original status code, content-type header and the content.

Useful for browsing original CMS data on staging GCS bucket:

go/iowastaging/debug/srvget?url=https://storage.googleapis.com/io2015-data-dev.google.com.a.appspot.com/manifest_v1.json

List contents of Google Drive AppFolder.

TODO

Send GCM push notifications

http://HOST/io2015/debug/push

Follow instructions on that page.

On staging server this is go/iowastaging/debug/push

Re-sync local datastore with remote

http://HOST/io2015/debug/sync

Testing

Frontend tests are run via https://github.com/Polymer/web-component-tester

Configuration is in wct.conf.js.

To run tests, install wct globally:

npm install -g web-component-tester

and run:

wct

ioweb2015's People

Contributors

alexmahan avatar brendankenny avatar devnook avatar ebidel avatar jeffposnick avatar paullewis avatar robdodson avatar samthor avatar tdreyno avatar wibblymat avatar x1ddos avatar yangchenyun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ioweb2015's Issues

Create one-off page that uses geolocation API for Extended Form

For us to be able to auto-populate the Extended map on the Website from the Extended Form organizers fill out we need to be able to pull the location data from their event.

Create a one-off page that allows users to type their event location, displays a map pin to verify the location is where they think it is, and opens the reg form with populated variables.

Example pre-populated form:
https://docs.google.com/a/google.com/forms/d/1rjMnxYvyGAmi3O4gfvYgqhEoolDSkeVdJY2w9MtVlmE/viewform?entry.23917865=country&entry.652280183=street&entry.502610227=123&entry.272782401=postcode&entry.789012978=city&entry.971996821=APAC%20(Asia%20Pacific)&entry.1458261258=lat&entry.1058533728=lng

(the entry.971996821 value needs to match one of the 3 options in the form)

Flow:

  1. use the Places API to auto-complete the users event location (similar to this demo)
  2. use the Maps Gecoding API to get the lat/lng from the full address.
  3. show a map pin for them to visually verify the location.
  4. Open the pre-popluated form like so: example

Form results: https://docs.google.com/spreadsheets/d/10b77CzFk_7SQ_BiWSkMf4bz2bawnE-doJS04YInsCIk/edit#gid=0

Master: Notifications

Context: in an event of data change the backend pushes a message to a Service Worker. For a push event to succeed, the SW has to show a UI notification to the user.

We have these categories of user groups:

  1. Authenticated / anonymous.
  2. Opted in for receiving push notifications.
  3. Starred sessions (talks): none or at least one.
  4. Combinations of the above.

Anonymous users cannot star sessions: we need a user ID to attach a starred session to.
Some users might have logged in but never starred a single session.

In an event of a data change, these users will be sent a push notification:

  1. change is related to a session of a user's interest (starred session).
  2. any user (both authenticated and anonymous) which has no starred sessions but opted in for push notifications.

We could make anonymous users received push notifications by simply storing their registration ID obtained from pushManager.register() as long as registrationId is constant (scoped to the visitor).

Updates

  • Need global on/off switch for notifications. Backend needs an endpoint for toggling this setting.
  • Frontend needs to show toast when the schedule is updated. This is for the case when users have the page open and should be informed there are updates. Alternatively, we can keep the frontend up to date in realtime with firebase if we go that route.

Brain dump:

  • If Chrome doesn't get notifications, we can't do them.
  • Notifications will work for Chrome mobile/desktop
  • Chrome notifications are planned for Chrome 42 (stable on April 14).
  • if the site is open, we can do web notifications for all browsers.
  • if the site is not open, we can only do notifications from sw (chrome only)

Pull in shed as an official dependency

It looks like shed is packaged as an npm module, but I don't think it's published. (Unless I'm missing it somewhere.)

We should work with @wibblymat to figure out whether we can start pulling it in via package.json instead of manually copying the source into the project (which was done in #26).

Page features that need to be updated dynamically

Noting what needs to change. I've done some of this in #92

  • Need a template variable for pages to set the masthead bg color. This is done through a class:
    <header class="masthead bg-medium-grey" layout vertical> (e.g. "bg-medium-grey" in this example).
  • nav bar selection updates on new page navigation. #navbar paper-tabs.selected needs to reflect the current page. Ideally, this would be data-bound to the url route <paper-tabs selected="{{route}}" valueattr="route"><paper-tab route="home"><paper-tab..>,
  • similarly, drawer panel nav updates to selected route.
  • the id of body: <body id="page-PAGENAME">, where PAGENAME is 'about', 'home', 'offsite', 'onsite',...etc.
  • <title>
  • <meta> tags that need to change

Clarify usage of the simpledb_polyfill.js library

#47 adds in a local copy of a library that wraps IndexedDB, written by a Googler, Joshua Bell, and published at https://gist.github.com/inexorabletash/c8069c042b734519680c

I need to contact him and clarify whether he considers this code ready to be used, and if so, whether he has plans for officially releasing it somewhere other than in that gist, so that it could be pulled in as an official dependency.

There are a few other libraries wrapping IndexedDB we could use if necessary, but his is particularly small and straightforward, and works well for our needs at this time.

Use responsive screenshots + diffs to ensure site looks "correct" prior to deployment

Some combination of pageres for generating screenshots of pages for various viewport sizes and an image diff tool (blink-diff, maybe?) to determine whether anything has changed from our current set of "golden" images could help prevent us from deploying changes that inadvertently affect site layout.

(There's also the automated-screenshot-diff package, but I don't think that gives us the responsive screenshot aspect, which is important.)

Don't hardcode window.DEV (or equivalent)

window.DEV = true is currently hardcoded in index.html and used in some logging and GA-related logic.

Also, the use of a boolean for detecting environment doesn't allow for different logic in dev vs. staging vs. prod, so something like window.ENVIRONMENT might be more useful. (I could imagine needing to tweak the GA cookie parameters for the staging environment.)

@crhym3 do you think setting this via a server-side template would make sense? Alternatively, we could set it via templating in the gulp build process.

Footer: social links share page. Don't use JS API

We need to link to the appropriate sharing option and not host any JS or use their JS APIs.
Something like:

shareGplus: function(e) {
  e.preventDefault();
  this.openPage_('https://plus.google.com/share?url=' +
                 encodeURIComponent(location.href) +
                 '&hl=' + encodeURIComponent(document.documentElement.lang));
},

shareFB: function(e) {
  e.preventDefault();
  this.openPage_('https://www.facebook.com/sharer.php?u=' +
                 encodeURIComponent(location.href) +
                 '&t=' + encodeURIComponent(document.title));

},

shareTwitter: function(e) {
  e.preventDefault();
  this.openPage_('https://twitter.com/share?text=' +
                 encodeURIComponent('Google I/O 2015 - blah blah') + '&url=' +
                 encodeURIComponent(location.href));
},

Experiment location & build tooling

Hi all,

We're trying to keep the experiment as separate as possible from the site, in terms of dependencies and commands to execute. The ultimate goal would be a Polymer component that could be link'd to from any Web Components site to turn their site into the experiment as well. This approach gives us a nice separation of responsibilities and makes sure our end presents a nice standard API without requiring much work on the app side.

So, I'm thinking we create a top-level folder for experiment and move the app-related build tooling and dependencies fully into app.

Finally, we can create either some simple shell scripts, Makefile or whatever to trigger actions in both folders. Something like:

make dev

or

make build

Thoughts?

UTM tracking

  • utm_source=web_app_manifest- app manifest
  • utm_source=schema_org_event

others?

Use clients.claim() when available

This isn't a high priority, but a potential optimization would be to disable AJAX-y navigations and use real browser navigations if we detect that 'serviceWorker' in navigator && navigator.serviceWorker.controller == null.

This indicates that the SW hasn't yet taken control of the page, most likely because it's the first time the user has visited. The SW won't start handling network requests until the next navigation to a page that's under the SW's scope (either a reload of the current page, or navigation to a new page), and that might be delayed much longer than it normally would due to AJAX-y navigations.

Permission to write to repo

Hi all,

I'm working on creating a new branch for the experiment integration, but it appears that I only have read-only access to this repo. Can @tdreyno and I have write access so that we can push the new branch?

Thanks!
-A

Impl dynamic page loading

We need a page loader to fetch content/redirect user to correct subpage as needed. The plan would be:

  1. Every page has a URL, e.g. /, /schedule/, /attend-on-site/ with appropriate section filled out and placeholders for other subpages.
  2. If you visit that URL you get all the HTML, JS and CSS needed for the page.
  3. If the page is loaded over AJAX we create a DOM fragment and querySelector out the bits we need
  4. We use a barebones container into which we inject the bits we want, then transition.

The alternative approach would be to render a shell page and fetch partials (instead of full pages) in case of ajax request.

The benefits for full-pages approach is SEO, simplicity (on the server side at least), cacheability for SW, and we can have discrete URLs (so in case of JS error we have a meaningful experience). There's very little bloat overall, because none of the assets (images, CSS, JS) returned in the HTML will be fetched until they are injected into the page, which most of them won't be.

Thep lan is to go with the full-page load direction, and only if we discover it adds to complexity or is causing a perf issue we strip back to partials.

Master: impl webgl globe

  • - handle viewport resizing - #453
  • - cycle through 10 city names - #111
  • - On page load, one of the locations is selected. The names cycle through the names until it hits the correct city name, then stops.#135
  • - GA events for glob interactions - #678
  • - "view 2014 events" on /offsite page using auto complete input- #677
  • - pins using /io2015/api/extended endpoint #680
  • - deep link from homepage
  • - fade in globes
  • - pin need popup info #700
  • - offsite globe should load somewhere where there is light -#707

GA: window.onerror reporting

// Track and log any errors to analytics
window.onerror = function(message, file, lineNumber) {
  // We don't want to trigger any errors inside window.onerror otherwise
  // things will get real bad, real quick.
  try {
    ga('send', 'event', 'error', file + ':' + lineNumber, '' + message);
  } catch (e){}
};

Add a gulp task for instrumentation/performance testing of dev build

Create a gulp task for measuring some basic performance metrics (e.g. time until the document is ready for each known page) and flag deviances from a baseline.

This is similar to what we could do with psi, but we can't use psi against our local dev builds. (This article about using ngrok probably isn't relevant, since I can't image we'll be able to set up the secure tunnel part.)

Server-side templating updates to for new ajax model

As part of #94, we're changing the way ajaxified pages are dynamically injected on the page.

To adapt to this change, the server needs to render the shell of the page (the reusable markup shared across all pages) as it is today. However, to server-side rendering on the initial page load, the server needs to now populate placeholder <template>s with a the correct partial .html file.

For example, when loading about.html, the server would render the index.html template and also populate the 2 template placeholders with the pieces of template/about_partial.html:

<template id="template-content-placeholder" ref="">
  innerHTML of about_partial.html's <template id="template-onsite-content">
</template>

It would also fill <template id=“template-about-masthead”>.

Upon user navigation, ajax injection takes over an the ref of each template is updated to the new page. Whatever the server rendered in template(s) on initial page load is no longer used :)

This setup will also allow us to remove one request on page load. We won't need to populate the templates on the client, the server will take care of it. SEO and speed friendly!

We currently have placeholder pages (about.html, schedule.html, onsite.html) that also need to be removed in favor of the server rendering the correct page.

@devnook

Page: implement attend offsite page

  • - page design
  • - recap video - #147
  • - download guide #141
  • - view 2014 events.
  • - "Watch the 2014 I/O Extended recap video" @monicabagagem what video is this?

"It has a 35% black scrim over the whole video with at 80% opacity 72px play button with the cta below it. The cta is Roboto Medium 16pt with box-shadow: .5px .5px 1px rgba(0, 0, 0, 0.25)
"
unnamed 1

Homepage: G+/Twitter #io15 posts

For homepage, query @googledevs and +GoogleDevelopers for latest few posts with hash tag #io15. We should eventually setup a server-side cron for this.

The links should be clickable in tweets and the username links to the tweet, just link twitter does.

We should hide the section until there are at least 3 tweets. That'll be easy with <template repeat=""> and <template if="{{}}">.

Define a preaching strategy

Service workers gives us the flexibility of precaching whatever resources we'd like (both local and cross-origin) during the install phase.

The temptation is to be aggressive and precache everything we might possibly need for all aspects of the site, but that does come at the cost of bandwidth consumption during the install phase of the service worker's lifecycle. This will be incurred across all clients every time we increment the service worker's cache versioning, so it's not even a one-time thing.

The code introduced in in #56 is one approach towards generating a list of resources to precache. As a starting point, the code in that PR is quite aggressive and pulls in almost everything. It needs to be refined when we agree upon a strategy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.