Summary:
Ref T12616. This puts "h" back to collapse or expand the current file.
This removes some very complicated/messy code around following links in the table of contents and getting files auto-expanded. I suspect no one will miss this, but we can restore it if ayone notices.
Test Plan: Pressed "h" to collapse/expand a file. Also used the menu items.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17940
Summary:
Fixes T10563. If you have a thread like this:
```
> A
> B
> C
```
...and you reply to "B", we should put the new inline below "B".
We currently do when you reload the page, but the initial edit goes at the bottom always (below "C").
Test Plan: {F4963015}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T10563
Differential Revision: https://secure.phabricator.com/D17938
Summary:
Ref T12616. When you "Delete" a comment from the preview, we try to delete the comment on screen too.
It may or may not be present on screen: if you just added it it's usually visible. However, you might also have hidden the file it contains or it could be on an older diff in a file which is no longer present in the current diff.
After updates in T12616, we could only find the comment if you'd previously interacted with it for some reason. Update this code to be able to find all inlines present in the document.
Test Plan:
- Write a draft comment.
- Reload the page.
- DO NOT INTERACT WITH THE COMMENT!
- Delete it from the preview.
- After patch: Comment is deleted from the document, too.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17937
Summary:
Fixes T11662. In the very obscure situation described in that task, quiet a JS console warning.
The actual edit operation appears to work correctly after changes elsewhere.
There aren't really any legitimate lines for us to highlight in this case so I'm just giving up rather than trying to do something approximate.
Test Plan:
- Wrote `long.txt`.
- Created revision.
- Added an inline near the bottom.
- Removed most of `long.txt`.
- Updated revsion.
- Replied to the ghost inline.
- Edited the reply to the ghost inline, worked.
- Hovered the reply to the ghost inline: no line highlight, but no errors.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11662
Differential Revision: https://secure.phabricator.com/D17930
Summary: Fixes T1026. Ref T12616. Allows drag-to-select on devices to add inlines on a range of lines, using dark magic that I copy/pasted from StackOverflow.
Test Plan: Left a comment on a range of lines on iPhone simulator.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616, T1026
Differential Revision: https://secure.phabricator.com/D17928
Summary: Ref T12616. This makes line range selection use the new code, and removes the remainder of the old "hover a line number" / "select a line range" code.
Test Plan: Hovered line numbers; selected line ranges.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17927
Summary:
Ref T11401. Fixes T5232. Ref T12616.
Partly, this moves more code over to the new stuff.
This also allows "r" to work if you have code selected (not just comments). If you "reply" to code, you start a new comment.
You can "R" a comment to quote it. This just starts a new comment normally if you "R" a block of code. This is sort of a power-user version of "quote" since it seems like it probably doesn't really make sense to put it in the UI ever (maybe).
With the new click-to-select, you can click + "R" to reply-with-quote.
Test Plan: Used "r" and "R" to reply to comments and code.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616, T11401, T5232
Differential Revision: https://secure.phabricator.com/D17920
Summary:
Fixes T8047. Ref T12616. Fixes T9270. This moves the "hover" part of the hover/drag behavior to the new code, leaving the "drag" part for a followup change.
The new hover UI behaves properly with Quicksand (T8047) and the filetree (T9270).
Test Plan: Hovered over inlines, saw lines select properly.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616, T9270, T8047
Differential Revision: https://secure.phabricator.com/D17919
Summary: Ref T12616. The ability to do {nav Edit > Cancel > Undo} to get your text back on inlines got dropped during the conversion. Restore it.
Test Plan:
Created, replied, and edited inlines, typed text, then cancelled. Was able to undo.
Also undid normal deletion.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17916
Summary:
Fixes T11784. A lot of things are interacting here, but this probably gets slightly better results slightly more often?
Basically:
- When we load content, we try to keep the viewport "stable" on the page, so the page doesn't jump around like crazy.
- If you're near the top or bottom of the page, we try to stick to the top (e.g., reading the summary) or bottom (e.g., writing a comment).
- But, if you followed an anchor to a comment that's close to the bottom of the page, we might stick to the bottom intead of staying with the anchor.
Kind of do a better job by not sticking to the bottom if you have an anchor. This will get things wrong if you follow an anchor, scroll down, start writing a comment, etc. But this whole thing is a pile of guesses anyway.
Test Plan:
- Followed an anchor, saw non-sticky stabilization.
- Loaded the page normally, scrolled to the bottom real fast, saw sticky stabilization.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11784
Differential Revision: https://secure.phabricator.com/D17911
Summary:
Ref T12616. Fixes T12715. I suspect these are very rarely used. (I think you tried to get rid of them before but I pushed back since we couldn't really offer great alternatives at the time?)
Now that the code is in a better place:
- Click an inline's header (just the colored part) to select it with the keyboard selection cursor.
- Click again to deselect it.
- You can use "n" and "p" to jump to comments, so "click + n" is the same as the old "V" action.
- This also makes it easier to swap between keyboard and mouse workflows, since you can jump into things with the keyboard at any inline.
Also, make "Reply" render more consistently.
Test Plan:
- Did all that stuff, things seemed to work OK.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12715, T12616
Differential Revision: https://secure.phabricator.com/D17908
Summary:
Fixes T8130. Allows selected comments to be shown/hidden (with "q") or marked done/not-done (with "w").
(These key selections are because "qwer" are right next to each other on QWERTY keyboards, and now mean "hide, done, edit, reply".)
Also, allow "N" and "P" to do next/previous inline, including hidden inlines. This makes "q" to hide/show a little more powerful and a little easier to undo.
Test Plan: Used "q", "w", "N" and "P" to navigate and interact with comments.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T8130
Differential Revision: https://secure.phabricator.com/D17906
Summary:
Ref T12634. Fixes T8131. Currently, most edit operations (edit, reply, collapse, mark done) lose the keyboard cursor state.
Instead, bind the state more tighlty to the inline object itself (instead of the rows which happen to be in the document), and then do a bit of recalculation to try to keep it selected across edits.
Test Plan:
- Used "n" to select an inline.
- Clicked "Done" checkbox.
- Pressed "n".
- Went to the next inline (previously: lost position in document).
- Behavior is also better for: edit, reply, collapse/expand.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12634, T8131
Differential Revision: https://secure.phabricator.com/D17905
Summary:
Ref T12634. Fixes T12633. These events allow the keyboard reticle to resize properly.
(I expect to possibly hide/disable the reticle in the future during edits, but at least make the behavior sensible for now.)
Test Plan:
- Used "n" to select a block.
- Clicked a line number in that block to start a new inline comment.
- Saw reticle resize properly.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12634, T12633
Differential Revision: https://secure.phabricator.com/D17904
Summary: Ref T12634. Fixes T10049. Toggling an inline currently leaves the reticle oddly-positioned.
Test Plan:
- Selected a comment with the keyboard.
- Collapsed it.
- Saw reticle behave reasonably.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12634, T10049
Differential Revision: https://secure.phabricator.com/D17903
Summary: Fixes T12632. Ref T12634. Currently, the keyboard focus reticle does not redraw properly after a window resize.
Test Plan:
- Used "n" to select a block.
- Resized the window.
- Saw the reticle also resize properly.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12634, T12632
Differential Revision: https://secure.phabricator.com/D17901
Summary: Ref T8047. Ref T12634. When we sleep, hide the reticle. Restore it when we wake.
Test Plan:
- With Quicksand enabled..
- Used "j" to select a change in a revision.
- Navigated away by clicking a link.
- WOW! Reticle vanished properly!
- Used "back" to return.
- Reticle returned properly.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12634, T8047
Differential Revision: https://secure.phabricator.com/D17900
Summary:
Ref T12634. Using keyboard shortcuts in Differential currently relies on focus behavior in `KeyboardShortcutManager`.
This possibly made sense long ago, but no longer does, and leads to a whole slew of bugs where the reticle doesn't interact properly with anything else.
Move it to Differential so it can be made reasonably aware of edit operations, Quicksand navigation, etc.
This just moves the code; future diffs will actually fix bugs.
Test Plan: Used "n", "j", etc., saw the same behavior as before.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12634
Differential Revision: https://secure.phabricator.com/D17899
Summary: Ref T12616. This makes "edit" and "reply" work again.
Test Plan:
Used "e" and "r" to edit and reply.
Also used them in bogus ways and got useful UI feedback.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17895
Summary: Ref T12616. This moves most keyboard shortcuts into DiffChangesetList. It breaks some shortcuts that I plan to restore later, noted in T12616 (toggle file, edit inline, reply to inline), since I think ripping them out now and rebuilding them in a little bit will make things much simpler.
Test Plan:
- Used j, k, n, p, J, K shortcuts to navigate a revision.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17859
Summary:
Ref T12616. This moves "reply" to the new stuff and deletes DifferentialInlineEditor, which no longer does anything.
(This breaks some keyboard shortcuts, but I'll rebase D17859 shortly.)
Test Plan: Replied to inlines; things seemed to work properly.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17894
Summary:
Ref T12616. This makes creating inlines use the new code.
Creation and editing is now slightly more consistent in how it uses nodes. This will simplify the next change (replies), which I ran into some trouble with in an earlier iteration.
Note that this (and other changes in the series) allow you to create and edit multiple inlines simultaneously. This is mostly a feature, although I expect we'll need to lock it down a little bit. I have some UI ideas to help avoid errors.
Test Plan: Created inlines on a single line; on a range of lines; on the same line; multiple inlines at the same time.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17893
Summary:
Ref T12616. This moves the delete actions to the new, more stateful way of doing things.
These are a little tricky because you can click "Delete" on an inline, but you can also click "Delete" from the preview area at the bottom of the page. If you do, the inline you are deleting may or may not be present on the page.
This has a few bugs -- notably, deleting from the preview without interacting with the on-page inline first won't actually delete the on-page inline yet -- but nothing too serious.
Test Plan: Deleted inlines, undid deletion, deleted from preview.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17890
Summary:
Ref T12616. This updates clicking the "Done" checkbox for the new stuff.
This one is pretty clean since the "Done" checkbox doesn't do too much weird magic.
Test Plan: Clicked the box a few times.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17888
Summary:
Ref T12616. This doesn't pull over everything (some UI feedback didn't make it yet, and you can't cancel + undo cancelling edits yet) but editing comments technically works.
This is a little shaky, but feels less shaky than every other approach I've tried, so I think I'm finally on a reasonable track here.
Test Plan: Edited some inline comments.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17887
Summary:
Ref T12616. Fixes T12153. Currently, when you hide inlines, they hide completely and turn into a little bubble on the previous line.
Instead, collapse them to a single line one-by-one. Narrowly, this fixes T12153.
In the future, I plan to make these changes so this feature makes more sense:
- Introduce global "hide everything" states (T8909) so you can completely hide stuff if you want, and this represents more of a halfway state between "nuke it" and "view it".
- Make the actual rendering better, so it says "epriestley: blah blah..." instead of just "..." -- and looks less dumb.
The real goal here is to introduce `DiffInline` and continue moving stuff from the tangled jungle of a million top-level behaviors to sensible smooth statefulness.
Test Plan:
- Hid and revealed inlines in unified and two-up modes.
- These look pretty junk for now:
{F4948659}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616, T12153
Differential Revision: https://secure.phabricator.com/D17861
Summary: Ref T12616. This cements the relationship between ChangesetList (parent container) and Changeset (child) and passes translations down so Changeset can use them to translate the text "Loading..."
Test Plan: Viewed loading changes.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17846
Summary: Ref T12616. This ends up being a little messy ("one giant function") and maybe I'll clean it up a bit later, but continue consolidating the wild jungle of behaviors into a smaller set of responsible objects.
Test Plan: Clicked all the menu options, saw them work properly. Grepped for removed methods.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17845
Summary:
Ref T12616. Diffusion, only, has a "Show All Context" button which expands the full context on all changes.
I don't remember the exact history on this, but it hasn't existed in Differential for some time and no one has complained. I suspect that the "View Options > Show All Context" on each file may replace it. I can't really come up with good reasons to use it, offhand. If we want to restore it, I think global options after T1591 is promising.
{F4945561}
Test Plan:
- Loaded a commit in Diffusion, no longer saw a button.
- Grepped for relevant sigils.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17843
Summary: Ref T12616. This class is already mostly-reasonable as a representation of an individual changeset, so I plan to just adjust it a little bit.
Test Plan:
- Used `git grep` to search for `ChangesetViewManager`.
- Used `git grep` to search for `changeset-view-manager`.
- Browsed around and interacted with changesets.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17842
Summary: Ref T12616. Put these listeners in DiffChangesetList so the wake/sleep properly for Quicksand.
Test Plan:
- Added some logging.
- With quicksand, moved between diffs.
- Saw "load" and "show more" fire exactly once on each page, with the correct changeset list listener.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616
Differential Revision: https://secure.phabricator.com/D17841
Summary:
Ref T12616. Ref T8047. Ref T11093. We currently have several bugs where diff state sticks across Quicksand pages.
Add a new top-level object to handle this, with `sleep()` and `wake()` methods. In `sleep()`, future changes will remove/deacivate all the reticles/editors/etc.
See T12616 for high-level discussion of plans here.
This general idea is likely to become more formal eventually (e.g. for "sheets" or whatever we call them, in T10469) but I think this is probably a reasonable place to draw a line for now.
Test Plan:
- Added some logging to sleep(), wake() and construct().
- Viewed changes in Differential.
- With Quicksand on, browsed around; saw state change logs fire properly.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12616, T11093, T8047
Differential Revision: https://secure.phabricator.com/D17840
Summary: Moves Conpherence to use EditEngine. This removes the "First Message" field, but I think that's ok until we have direct messaging of some sort, then maybe have built-ins cover that case.
Test Plan:
- Visit /new/ and /edit/ for creating new rooms.
- Edit a room in full conpherence
- Edit a room in durable column
- grep for METADATA calls
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T11729
Differential Revision: https://secure.phabricator.com/D16677
Summary: This adds some basic per user / per room theming for Conpherence, which should hopefully let users identify rooms from just the sidebar color.
Test Plan: Lots of threads with different colors.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D17747
Summary:
Ref T12562. I think the pre-send-on-enter behavior was: disable textarea, send message, clear area on response?
That got changed but not completely, maybe. There's currently an issue here:
- Add a `sleep(3)` to `UpdateController`.
- Type "AAA".
- Press enter.
- Real fast, type "BBB".
- When the "AAA" arrives, your "BBB" is lost. Sad!
Test Plan:
- Did the thing described above; no longer lost "BBB".
- Switched threads, sent messages, couldn't find anything else this breaks. It dates from a long time ago so I think it's just pre-SOE stuff.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12562
Differential Revision: https://secure.phabricator.com/D17742
Summary:
Fixes T12599. If you're faster than the network request, we don't actually resolve your query when the data arrives.
Instead, when the data shows up, run the query if the user has typed something.
Test Plan: Pasted a filename in real fast, got results. (Previously: no results until you press something else.)
Reviewers: amckinley
Reviewed By: amckinley
Maniphest Tasks: T12599
Differential Revision: https://secure.phabricator.com/D17739
Summary:
Ref T12566. Ref T12563. This fixes three bugs with Aphlict replay stuff:
First, Conphernece would try to repaint the UI even if no thread was open. Only repaint when a thread is open.
Second, although we deduplicate JX.Leader messages, we didn't deduplicate actual notification messages. If you browsed the leader window, then it re-elected itelf as a leader and replayed history, it could rebroadcast notifications and other windows could show doubles. Deduplicate notifications to prevent this.
Third, we always replayed the last 60 seconds of history. When you browsed the leader window, whichever window became the new leader (possibly the one you just browsed) could replay messages from before it had opened, leading to duplicate messages. Particularly, after receiving a message and then browsing you could see that message again. Instead, only replay history as far back as when the window first opened.
Test Plan:
- Clicked "Repaint" with a thread open, saw a repaint. Clicked "Repaint" with Conpherence open but no thread, no repaint and no 404 request to `/update/null/`.
- In browser A, opened three windows. In browser B, sent a notification. In browser A, browsed the leader window away twice in a row. Observed that the window which never became a leader doesn't duplicate notifications.
- In browser A, opened three windows. In browser B, sent a notification. In browser A, browsed the leader window away over and over again. Observed that replay requests issued with appropriate history windows.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12566, T12563
Differential Revision: https://secure.phabricator.com/D17722
Summary: Ref T12573. This sends a "ping" to the server, and a "pong" back to the client, every 15 seconds. This tricks ELBs into thinking we're doing something useful and productive.
Test Plan: Ran `bin/aphlict debug`, loaded Phabricator, saw ping/pong in logs.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12573
Differential Revision: https://secure.phabricator.com/D17717
Summary: Ref T12566. When we reconnect, refresh the current thread even if we replayed notifications.
Test Plan:
- Clicked the "Repaint" button, saw the thread refresh.
- Clicked the "Reconnect" button, saw the thread reresh.
- Launched `aphlict debug`, killed it, restarted it, saw the thread refresh after reconnect.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12566
Differential Revision: https://secure.phabricator.com/D17713
Summary:
Fixes T12564. We already had some code which seems to deal with this properly, it just wasn't getting used.
Assign each application-level notification a unique ID, then ignore messages with duplicate IDs.
Test Plan:
- In browser A, loaded `/T123`.
- In browser B, loaded `/T123`.
- Made a comment as B.
- Saw notification as A.
- Mashed "Replay" a bunch.
- Before patch: piles of duplicate notifications.
- After patch: no duplicates.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12564
Differential Revision: https://secure.phabricator.com/D17710
Summary:
Fixes T12563. If we've ever seen an "open", mark all future connections as reconnects. When we reconnect, replay recent history.
(Until duplicate messages (T12564) are handled better this may cause some notification duplication.)
Also emit a reconnect event (for T12566) but don't use it yet.
Test Plan: {F4912044}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12563
Differential Revision: https://secure.phabricator.com/D17708
Summary: Ref T12568. Ref T12567. Allows you to force a reconnect, and shows the reconnect delay on connection close/failure.
Test Plan: {F4911879}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12568, T12567
Differential Revision: https://secure.phabricator.com/D17705
Summary: Ref T12568. This begins building toward a more useful realtime debugging console for Leader/Aphlict/general realtime stuff.
Test Plan: {F4911521}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12568
Differential Revision: https://secure.phabricator.com/D17701
Summary: Fixes T12556 Uses more common components in ConpherenceThreadList by moving to PHUIListItemView. Reduces clutter by moving privacy into the header. Gets ride of "See More" double interchanges.
Test Plan:
I need to test this more, doesn't seem to auto-select top room any more, also might build a lipsum generator.
- Create lots of rooms with various policies
- Test clicking on policy object
- Click on different rooms
- Post in rooms
- Load up second account, see room numbers
- Clear room message count by clicking on room
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T12556
Differential Revision: https://secure.phabricator.com/D17698
Summary: Fixes T12138. Test for the presence of being in fullscreen mode, and disable send on enter if present. Side note, I'd love a first class "hasClass" type Javelin function.
Test Plan:
- Go to Conpherence
- Type some smack, see it send on enter
- Go fullscreen like a boss
- Let the words flow
- Close fullscreen, then send on enter.
- (might be nice someday to add a "submit" button to fullscreen editor)
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T12138
Differential Revision: https://secure.phabricator.com/D17590
Summary:
Ref T12314. Ref T6064. Ref T11580. If an install defines several different task create forms (like "Create Plant" and "Create Animal"), allow any of them to be created directly onto a workboard column.
This is just a general consistency improvement that makes Custom Forms and Workboards work together a bit better. We might do something fancier eventually for T6064 (which wants fewer clicks) and/or T11580 (which wants per-workboard control over forms or defaults).
Test Plan:
- Created several different types of tasks directly onto a workboard.
- Faked just one create form, saw the UI unchanged (except that it respects any renaming).
{F3492928}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12314, T11580, T6064
Differential Revision: https://secure.phabricator.com/D17446
Summary:
See downstream <https://phabricator.kde.org/T5404>. This code was doing some `.firstChild` shenanigans which didn't survive some UI refactoring.
This whole UI is a little iffy but just unbreak it for now.
Test Plan: Allowed and rejected desktop notifications, got largely reasonable UI rendering.
Reviewers: chad
Reviewed By: chad
Differential Revision: https://secure.phabricator.com/D17388
Summary: Fixes T12248. Adds a flag for movable panels, and only allows those to be moved. Also cleaned up some CSS rules missing once a panel was drug into a new position.
Test Plan: Try to drag a tab panel content pane, cannot. Drag normal pane, see CSS, grab and drag same panel back, CSS looks the same.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T12248
Differential Revision: https://secure.phabricator.com/D17356