Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting services through extensions #55

Open
stephenwf opened this issue May 19, 2018 · 0 comments
Open

Supporting services through extensions #55

stephenwf opened this issue May 19, 2018 · 0 comments

Comments

@stephenwf
Copy link
Owner

stephenwf commented May 19, 2018

An idea for supporting services.

At some point in the flow, when a service is available (either automatic or user-driven, not sure). A redux event announcing a service has been found is raised:

{
  type: 'SERVICE_ANNOUNCE',
  payload: {
    resource: { schema: 'manifest', id: 'http://.../' },
    service: 'http://serviceid/'
  }
}

If an extension is installed (via saga or middleware) it could listen for these events and respond if it implements the service.

function* imageServiceSaga() {
  yield takeEvery('SERVICE_ANNOUNCE', function *({ payload }) {
     if (isImageService(payload)) {
         yield put({ type: 'IMAGE_SERVICE_IMPORT', payload });
         // other instantiation logic..
         
         // Finally let redux know its accepted
         yield put({ type: 'SERVICE_ACTIVATED', {
          payload: { 
            service: payload.service, 
            id: 'my-image-service',
            label: 'My great image service',
          }
        });
     }
  });
}

This will go back to redux, and allow it to keep track of available extensions, and if they loaded successfully. It also allows redux to expose some methods:

  • isServiceActive
  • isServiceExtensionEnabled
  • enableExtensionService
  • disabledExtensionService
  • getServiceExtensions (on resources)

Which will provide a standard model for enabling/disabling them. The extensions can also listen for these events as they get fired and react as needed.

It would be likely that services would expose UI components of some form, or at very least state selectors that can power custom components. This should all fit into this model to allow any custom service to be bootstrapped, but still known to IIIF Redux.

As for end-users creating UIs that use image services:

How the API could work

class MyComponent extends Component {

  componentWillMount() {
    const { id, imageServiceExists, dispatch } = this.props;
  }
  
  render() {
    const { id, imageService, imageServiceActive, imageServiceExists } = this.props;
    
    if (!imageServiceExists) {
      return <div>No image available.</div>;
    }
    
    
    if (!imageServiceActive) {
      return <div>Loading...</div>;
    }
    
    return (
      <div>
        <h2>Image:</h2>
        <ImageServiceComponent id={imageService} target={id} />
      </div>
    );
  }

}

export default connect(
  canvasByIdSelector(api => ({
    imageServiceActive: api.isServiceActive('image-service'),
    imageServiceExists: api.isServiceExtensionEnabled('image-service'),
    imageService: api.getServiceForExtension('image-service'),
  })
))(MyComponent)

With image service maybe looking like this, using the custom selectors:

class ImageServiceComponent extends Component {
  render() {
    const { tileSource, thumbnail } = this.props;
    <div>
     <img src={thumbnail} width={200} />
     {/* Maybe do something with tile source, pass to OSD? */}
    </div>
  }
}

export default connect(
  imageServiceByIdSelector((api, props) => ({
    tileSource: api.getTileSource,
    thumbnail: api.getThumbnailAtSize(props.thumbnailSize || 200).
  }))
)

Although it would be likely that these services would have components themselves that you can simply drop in that provide this functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant