- 18 Dec, 2015 1 commit
-
-
Robert Knight authored
Experience has taught us that the client needs the session data (current user, list of groups) and set of enabled feature flags at the same time, and also needs to invalidate them in the same scenarios (eg. account switching). Fetching this data via two separate requests made it more complicated to ensure the client had a consistent view of session and feature-flag data. To simplify things and also same a network request: * On the server, put the feature flag data into the session data payload. * On the client, use the existing central storage and cache management for the session data payload to manage feature flags as well. The features service now becomes a thin wrapper around part of the session state.
-
- 16 Dec, 2015 1 commit
-
-
Nick Stenning authored
Don't crash on non-JSON body
-
- 15 Dec, 2015 3 commits
-
-
Robert Knight authored
Enable showdown's literalMidWordUnderscores
-
Sean Hammond authored
This stops showdown from interpreting underscores in the middle of words as <em> and <strong>, instead it treats them as literal underscores. Example: some text with__underscores__in middle will be parsed as <p>some text with__underscores__in middle</p> Fixes #2598 (URLs with _'s in them were getting <em> tags inserted into them, breaking the links). Also see <https://github.com/showdownjs/showdown/issues/211>.
-
Nick Stenning authored
Small tweaks to the header for re-use in the blog
-
- 14 Dec, 2015 35 commits
-
-
Robert Knight authored
Don't update annotations with contents of others
-
Sean Hammond authored
When listening to the 'annotationUpdated' event, AnnotationController needs to check that it's this annotation that the event refers to before acting on it. Fixes #2799.
-
Robert Knight authored
Annotation controller domain model view model refactor
-
Sean Hammond authored
-
Sean Hammond authored
-
Sean Hammond authored
If the user creates annotations while signed out and then signs in, we want those annotations to still be present in the sidebar after sign in, rather than being lost. Commit 7a1b5ca8d99252d3a086a8a8103fca4702521d06 had inadvertently broken this. The problem is that app.coffee destroys all AnnotationController instances on sign in, and only creates new instances for those annotations that have drafts. 7a1b5ca8d99252d3a086a8a8103fca4702521d06 removed a spurious call to saveToDrafts() in vm.edit() but it turns out that this call was (apparently inadvertently) the only thing that was causing drafts of annotations created while signed out to be saved, and hence the only thing causing these annotations to persist across sign ins. So add a listener for the USER_CHANGED event and save drafts of annotations on sign in, just before the AnnotationControllers get destroyed.
-
Sean Hammond authored
-
Sean Hammond authored
Update AnnotationController's view model on the "annotationUpdated" event. This fixes an issue that "live updates" were not being shown on annotation cards. The "annotationUpdated" event is fired by AnnotationController itself after successfully saving updates to an already-saved annotation. It's also fired by annotationMapper after received an updated annotation from the server (that was updated by a different client - the "live updates" feature). Subscribing to this event allows one function in AnnotationController to handle updating the view model in both cases.
-
Sean Hammond authored
Update AnnotationController's view model (vm) after successfully saving a new annotation to the server for the first time. This fixes two issues: 1. vm.annotationURI (which depends on the annotation's id, which is not present until the save to the server succeeds) was not being set correctly after successful save, so the annotation permalinks were not correct until you reload them. 2. If you created a highlight while logged out, then logged in, (AnnotationController automatically saves the highlight to the server for you on login) the "Only Me" icon was not being shown on the highlight until you reloaded it because vm.isPrivate wasn't set.
-
Sean Hammond authored
We only need to save an annotation to drafts when the focused group changes while editing it, and not at other times (e.g. when opening the editor??). We only need to restore an annotation from drafts when editing it, and not at other random times. Also, don't call updateViewModel() in init() after calling edit(), because this will overwrite the draft changes that you just restored.
-
Sean Hammond authored
Don't change the value of domainModel.group when the focused group changes. Instead, change it to groups.focusedGroup() in updatedDomainModel() before the annotation is sent to the server. This fits with the idea that domainModel is a read-only copy of the annotation that we received from the server, and vm is the read-write copy. But there's no vm.group as this would always be the same as groups.focusedGroup().
-
Sean Hammond authored
Recent changes broke the reverting of unsaved changes to annotations (AnnotationController.vm.revert()) when the user presses the _Cancel_ button on the annotation editor. The annotation's privacy was not being restored to its previously saved value. We can't set domainModel.permissions when the user changes the privacy of an annotation that they're editing, because if the user clicks _Cancel_ we need to revert the privacy back to its previous value (which we've just overwriten). So instead add a new vm.isPrivate boolean and set that instead: - vm.isPrivate() method (which returned true or false based on the value of domainModel.permissions) is replaced with a vm.isPrivate boolean. - updateViewModel() now sets vm.isPrivate according to the value of domainModel.permissions. - updatedDomainModel() nows sets domainModel.permissions according to the value of vm.isPrivate. - setPrivacy() nows sets vm.isPrivate instead of domainModel.permissions. - We no longer change domainModel.permissions when the focused group changes (it will continue to hold shared permissions for the previous group, but these will be updated by updatedDomainModel() before saving them to the server). vm.isPrivate doesn't need to be changed when the focused group changes because its value is independent of the focused group. - saveToDrafts() now saves vm.isPrivate instead of vm.isPrivate() - restoreFromDrafts() now restores vm.isPrivate instead of domainModel.permissions
-
Sean Hammond authored
These were being converted from view model to domain model format before being stored in drafts, and back again after being retrieved, which of course is pointless.
-
Sean Hammond authored
-
Sean Hammond authored
-
Sean Hammond authored
-
Sean Hammond authored
-
Sean Hammond authored
-
Sean Hammond authored
-
Sean Hammond authored
-
Sean Hammond authored
vm.document was a variable containing data duplicated from domainModel (not an exact copy, but data extracted from domainModel anyway). It's just easier to have a method for getting this - saves having to manage another variable and update it at the correct times. In making this change I noticed that there were several tests for updateViewModel() that were actually tests for extractDocumentMetadata() (which updateViewModel() was calling). These tests are no longer valud since updateViewModel() no longer calls extractDocumentMetadata(), and there are already duplicate unit tests of extractDocumentMetadata() itself. This leaves the describe('updateViewModel()') empty of tests, and since updateViewModel() is now pretty trivial, I decided just to delete the describe() rather then leave it empty or think up some tests to add to it.
-
Sean Hammond authored
I'm not sure this description adds much, and the comment about using annotationMapper for persistence is wrong.
-
Sean Hammond authored
Clarify what this object actually is: the read-write variables for the templates to write via ng-model.
-
Sean Hammond authored
This variable is just duplication of vm.annotation.tags and is not used by the templates.
-
Sean Hammond authored
A bug had crept in where if you changed the privacy of an annotation that you were creating or editing (by changing the selection in the _Post_ dropdown) then the privacy would not change and your text and tags edits would be deleted. This was happening because when you change the selection in the Post dropdown then onSetPrivacy() makes a change to the domain model which triggers onDomainModelChange() which copies the domainModel over vm.annotation, overwriting your changes. To fix this get rid of onDomainModelChange(). These sorts of functions (ones that are triggered by events or changes) create confusion by making it difficult to predict or trace the flow of execution, and I can't see why onDomainModelChange() needs to exist. This does deliberately remove one feature: If you had saved edits for an annotation in the drafts service (for example if you edited an annotation, made some changes, then changed the focus to a different group without saving the annotation) and _then_ someone using a different instance of the client (e.g. yourself on a different device, I guess) saved a change to that same annotation to the server, then this change would be communicated from the server to the first client (via the WebSocket I guess) and the first client would *delete your saved edits from the drafts service*. This behaviour was deliberate but I'm not sure why it was considered a good idea, and removing it simplifies things.
-
Sean Hammond authored
Deduplicate and correct code in AnnotationController for deciding whether an annotation is a reply.
-
Sean Hammond authored
Remove all the properties that don't need to be in vm.annotation from vm.annotation. This means removing all the read-only properties (id, target, updated, user) and leaving only the read-write ones that the templates write via `ng-model` (vm.annotation.tags and vm.annotation.text). The templates still do need read-only access to id, target, updated and user, but rather than _duplicating_ these values by copying them from domainModel to vm.annotation, instead add accessor methods vm.id() etc that just return the values from domainModel. This has two advantages: 1. Data is not duplicated between domainModel and vm.annotation. 2. It's clear that these fields are read-only, since the templates literally can't write them, at least in the case of id, user and updated target is unfortunately a mutable object so the templates could still mutate it. vm.target() could return a copy to avoid this but I haven't gone that far.
-
Sean Hammond authored
When saving an annotation to the server, the object that we actually send to the server is: 1. `domainModel`, after being updated by `updateDomainModel()`, in the case of creating a new annotation, or 2. The temporary local variable `updatedDomainModel` in the case of editing an existing annotation `vm.annotation` is never the object that gets sent to the server. So pass `domainModel` or `updatedDomainModel` to `validate()`, not `vm.annotation`.
-
Sean Hammond authored
Separate updateViewModel() and restoreFromDrafts() into two separate functions.
-
Sean Hammond authored
-
Sean Hammond authored
Explicitly store `private` (boolean), `tags` (array of strings) and `text` (string) in drafts instead of a "black box" `changes` object. Also rename the updateDraft() function to saveToDrafts() and move it out of AnnotationController.
-
Sean Hammond authored
Extract the translation of tags in AnnotationController from domainModel.tags format to vm.tags format and vice-versa into functions. This is for clarity, and so that the transformations can be used in multiple places in the code without duplication.
-
Sean Hammond authored
Copy individual properties into vm.annotation explicitly, instead of blindly copying all of domainModel into it. This allows us to see what's in there and start making decisions about what should/shouldn't be in there.
-
Sean Hammond authored
Since vm.annotation.permissions is (soon) no longer going to be used, don't validate it in validate(), validate model.permissions instead.
-
Sean Hammond authored
-