Git Product home page Git Product logo

popcorn's Issues

push service worker

<link rel="manifest" href="/manifest.webapp">

manifest.webapp

{
	
	"splash_screens": [],
	"scope": "/",
	"start_url": "/?utm_source=homescreen",
	"display": "standalone",
	"theme_color": "#434343",
	"background_color": "#f7f9f9",
	"prefer_related_applications": true,
	"related_applications": [{
		"platform": "ios",
		"url": "https://itunes.apple.com/us/app/popcorn/applID"
	}, {
		"platform": "play",
		"id": "com.playstore"
	}],
	"chrome_related_applications": [{
		"platform": "web",
		"url": "https://popcorn.com"
	}, {
		"platform": "android",
		"url": "https://play.google.com/store/apps/details?id=com.popcorn"
	}, {
		"platform": "chrome",
		"url": "https://chrome.google.com/webstore/detail/chromeStoreid"
	}],
	"permissions": ["notifications"],
	"gcm_sender_id": "gcmId",
	"gcm_user_visible_only": true
} 

pushWorker.js

/*global define:false, console, self, Promise */

// https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features
// https://developers.google.com/web/fundamentals/engage-and-retain/push-notifications/permissions-subscriptions
// https://github.com/w3c/ServiceWorker/blob/master/explainer.md
// chrome://inspect/#service-workers
// https://serviceworke.rs

//
// Env Setttings
//

// It's replaced unconditionally to preserve the expected behavior
// in programs even if there's ever a native finally.
Promise.prototype['finally'] = function finallyPolyfill(callback) {
    var constructor = this.constructor;

    return this.then(function(value) {
            return constructor.resolve(callback()).then(function() {
                return value;
            });
        }, function(reason) {
            return constructor.resolve(callback()).then(function() {
                throw reason;
            });
        });
};

var DEBUG = false;

//
// Utils
// 

function log(msg, obj) {
    console.log('PushWorker', msg, DEBUG ? obj : undefined);
}

function postMessage(msg) {
    if (DEBUG) {
        log("postMessage", msg);   
    }
    return self.clients.matchAll().then(function(clients) {
        return Promise.all(clients.map(function(client) {
            return client.postMessage(msg);
        }));
    });
}

function showNotification(payload) {

    // Cast has object
    if (typeof payload === 'string') {
        payload = {
            title: payload
        };
    }

    // Clear bad icons
    if (
        typeof payload.icon === 'string' &&
            payload.icon.indexOf('https://') !== 0
    ) {
        delete payload.icon;
    }

    // Clear bad badge
    if (
        typeof payload.icon === 'string' &&
            payload.badge.indexOf('https://') !== 0
    ) {
        delete payload.badge;
    }

    // Force requireInteraction
    if (typeof payload.requireInteraction === 'undefined') {
        payload.requireInteraction = true;
    }

    if (typeof payload.actions === 'undefined') {

        // Open/Close payload.data
        payload.actions = payload.data ? [
            {
                action: 'open', 
                title: 'Open'
            },
            {
                action: 'close', 
                title: 'Dismiss'
            }

        // Close (no payload.data)
        ] : [
            {    
                action: 'close', 
                title: 'Close'
            }
        ];
    }

    // Send via postMessage
    postMessage({
        event: 'push',
        data: payload
    });

    return self.registration.showNotification(payload.title, {
        lang: payload.lang || 'en',
        body: payload.body || 'Hello!',
        tag: payload.tag || payload.title,
        icon: payload.icon,
        badge: payload.badge,
        actions: payload.actions,
        data: payload.data,
        renotify: !!payload.renotify,
        requireInteraction: !!payload.requireInteraction,
        vibrate: payload.vibrate,
        sound: payload.sound,
        silent: (payload.silent || (!payload.sound && !payload.vibrate))
    });
}

function openUrl(url) {
    return self.clients.matchAll({
        includeUncontrolled: true, 
        type: 'window'
    }).then(function(clientList) {

        var clientListMatchUrl;

        // Look for a match
        if (url) {
            clientListMatchUrl = clientListMatchUrl && clientListMatchUrl.filter(function (client) {
                return String(client.url).indexOf(url) === 0;
            });

            if (clientListMatchUrl && clientListMatchUrl.length === 0) {
                clientListMatchUrl = clientList;
            }
        }

        if (clientList && clientList.length > 0) {
            return clientList[0].focus();
        } else if (url) {
            return self.clients.openWindow(url);
        }
    });
}

//
// Worker
//

log('Started', self);

self.addEventListener('install', function(event) {
    log('Install...', event);
    event.waitUntil(self.skipWaiting().finally(function () {
        log('Installed', event);
    }));
});

self.addEventListener('activate', function(event) {
    event.waitUntil(self.skipWaiting().then(function () {
        self.clients.claim();  
    }).finally(function () {
        log('Activated', event);
    }));
});

self.addEventListener('message', function (event) {
    log('Push event received', event);
});

// Register event listener for the 'push' event.
var lastPayload;
self.addEventListener('push', function(event) {
    try {
        var payload = event.data ? JSON.parse(event.data.text()) : {};
            
        // Keep the service worker alive until the notification is created.
        event.waitUntil(
            // Show a notification with title 'ServiceWorker Cookbook' and body 'Alea iacta est'.
            showNotification(payload)
        );

    } catch(err) {
        log('Push message parse failed', err);
    }
});

self.addEventListener('notificationclick', function(event) {
    log('Notification clicked', event);
    var action = event.action || 'open';
    if (action === 'open') {  
        event.notification.close();
        event.waitUntil(openUrl(event.notification.data));
    } else if (action === 'close') {  
        event.notification.close();  
    } 
}, false);

self.addEventListener('message', function (event) {
    if (event.data === 'PushTest') {
        log('PushTest...', event);
        event.waitUntil(
            showNotification({
                title: 'Push Notification Test',
                data: self.location.href
            })
        );   
    }
});

Trailer player issues

  • should stop video on mobile when close
  • should not stop video on orientation change
  • should at or open details we click on already selected movie.

Keyboard navigation would be nice

I'd expect left and right to change when pressed, and maybe do so continuously when held down. Though the flow itself probably needs to offer APIs to do this .

Add a "Made with Montage" link

Since people might arrive straight to the demo and not over montagejs.org.

Could be added to all demos.. not big, just small in the corner.

Movie's detail not updated when using the scroll wheel

When you "scroll" through movies using the mouse's wheel, the movie detail section does not correspond to the movie currently displayed at the center of the flow but to the last movie you have clicked on.

This issue occurs on Chrome Dev Version 36.0.1933.0 dev on Mac OS X 10.9.2

Fix deprecated use 'values' instead warnings

index.html.bundle-0.js:7 'properties' block is deprecated, use 'values' instead 
t.deprecationWarning @ index.html.bundle-0.js:7
index.html.bundle-0.js:7 'bindings' block is deprecated, use 'values' instead 
t.deprecationWarning @ index.html.bundle-0.js:7

Drag Issue

When running the Popcorn demo on my Galaxy Tab 10.1 with ICS and the latest Chrome browser...

Selecting a movie that's currently unselected by dragging it requires way more touch travel than what's expected. I expected that if I started a drag in the center of an unselected movie and moved my finger to the center of the demo's UI, that the movie would be selected. Instead it required significantly more touch travel past the center.

At first, I thought this might be typical drag lag, but it seems like it's a bug in the design/implementation of the demo.

Tap/Click on poster to select

Currently the only way to choose a movie poster is by flicking the central one to the left or right, that's not too obvious for some users.

Most people will try to tap/click on the movie poster to focus it, just like in any other coverflow-like UIs.

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.