Last active
August 29, 2015 14:03
-
-
Save seanhess/9e5998bed279f237480e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import _ = require('lodash') | |
export interface ModalConfig { | |
modalUrl:string; | |
state:string; | |
} | |
export interface Modal { | |
modalUrl: string; | |
state: string; | |
} | |
export class ModalsProvider { | |
private $location:ng.ILocationService; | |
private $state:ng.ui.IStateService; | |
private modals:Modals; | |
constructor( | |
private $urlRouterProvider:ng.ui.IUrlRouterProvider | |
){ | |
this.modals = new Modals() | |
} | |
// injected | |
$get($location, $state) { | |
this.modals.$location = $location | |
this.modals.$state = $state | |
return this.modals | |
} | |
// url needs to be a URL type, | |
modal(config:ModalConfig):Modal { | |
var modal:Modal = { | |
state: config.state, | |
modalUrl: config.modalUrl, | |
} | |
this.$urlRouterProvider.when(config.modalUrl, ($state, $location) => { | |
this.modals.handleUrl(modal, $state, $location) | |
}) | |
this.modals.add(modal) | |
return modal | |
} | |
} | |
export class Modals { | |
public current:Modal; | |
public parentUrl:string; | |
private modals:Modal[]; | |
// injected manually after constructor | |
public $location:ng.ILocationService; | |
public $state:ng.ui.IStateService; | |
constructor() { | |
this.modals = [] | |
} | |
get(state:string):Modal { | |
return _.find(this.modals, (m:Modal) => m.state == state) | |
} | |
open(state:string, search:Object) { | |
this.parentUrl = this.$location.url() | |
this.current = this.get(state) | |
if (!this.current) { | |
throw new Error("Could not find modal: " + state) | |
} | |
this.$location.url(this.current.modalUrl).search(search).replace() | |
} | |
close(changeUrl?:boolean) { | |
// Pass 'true' to also change url. Leave blank or pass 'false' to close without changing url | |
if (changeUrl) this.closeUrl() | |
this.parentUrl = null | |
this.current = null | |
} | |
closeUrl() { | |
if (this.parentUrl) { | |
this.$location.url(this.parentUrl).replace() | |
} | |
else { | |
this.$state.go('home') | |
} | |
} | |
get isOpen() { | |
return !!this.current | |
} | |
add(modal:Modal) { | |
this.modals.push(modal) | |
} | |
handleUrl(modal:Modal, $state:ng.ui.IStateService, $location:ng.ILocationService) { | |
// TODO: would be better if this didn't always require search, but could work with paths | |
if (this.parentUrl) return null // because it is already open | |
$state.go(modal.state, $location.search()) | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface PageStackSettings { | |
url:string; | |
templateUrl?:string; | |
controller?:Function; | |
controllerAs?:string; | |
abstract?:boolean; | |
reloadOnSearch?:boolean; | |
} | |
var PAGE_STACK_PREFIX = "stack-" | |
var PAGE_STACK_REGEX = /\.stack.*$/ | |
var PAGE_STACK_EMPTY = "empty" | |
export class PageStackProvider { | |
constructor( | |
private $urlRouterProvider, | |
private $stateProvider | |
) {} | |
stack(stateName:string, baseStates:string[], settings:PageStackSettings) { | |
// Add one url handler for the whole stacked state | |
// This gets called whenever the url is hit | |
// and we always use the url to get here | |
this.$urlRouterProvider.when(settings.url, function($match, $state) { | |
var nextState = stateName | |
var base = PAGE_STACK_EMPTY | |
if ($state.current.name) { | |
base = $state.current.name.split('.')[0] | |
if (baseStates.filter((name) => name == base).length == 0) | |
base = "empty" | |
} | |
nextState = base+".stack-" + stateName | |
$state.go(nextState, _.clone($match)) | |
return true | |
}) | |
// Add a state for each of the bases, in order | |
baseStates.forEach((baseState:string) => { | |
var localSettings:PageStackSettings = { | |
url: "^"+settings.url, | |
templateUrl: settings.templateUrl, | |
} | |
if (settings.controller) localSettings.controller = settings.controller | |
if (settings.controllerAs) localSettings.controllerAs = settings.controllerAs | |
if ('abstract' in settings) localSettings.abstract = settings.abstract | |
if ('reloadOnSearch' in settings) localSettings.reloadOnSearch = settings.reloadOnSearch | |
var fullStateName = baseState+"."+PAGE_STACK_PREFIX+stateName | |
// console.log("ADDING STATE", fullStateName, localSettings) | |
this.$stateProvider.state(fullStateName, localSettings) | |
}) | |
return this | |
} | |
$get($state) { | |
return new PageStack($state) | |
} | |
} | |
export class PageStack { | |
constructor(private $state) {} | |
hide() { | |
console.log("HIDE") | |
var name = this.$state.current.name | |
var baseState = name.replace(PAGE_STACK_REGEX, "") | |
this.$state.go(baseState) | |
} | |
isShown() { | |
return this.isOverGallery() && !!this.$state.current.name.match(PAGE_STACK_REGEX) | |
} | |
isOverGallery() { | |
return !this.$state.current.name.match(PAGE_STACK_EMPTY) | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pageStackService = require('./PageStackService') | |
import modalUrlProvider = require('./ModalUrlProvider') | |
export var module = angular.module('app.services', ['ui.router']) | |
.provider("$stack", pageStackService.PageStackProvider) | |
.provider('Modals', modalUrlProvider.ModalsProvider) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment