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

Fix multiple definition fetch issue #90

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1bc3ae0
Clean workspace update
yoching Apr 12, 2024
8c0cd2d
Update to use decodeList
yoching Apr 12, 2024
4311ed8
Update storybook Workspace to use `open` of Workspace for data fetch
yoching Apr 26, 2024
7396818
Clean workspace
yoching Apr 26, 2024
b52b2dc
Add single_name_multiple_entry sample
yoching May 4, 2024
33b9c34
Update to decode reference from api response
yoching May 25, 2024
12e4054
Update items replace part so that it's updated with parsed items
yoching May 25, 2024
41b0e3a
Add more samples
yoching May 25, 2024
55d22bb
Clean some functions
yoching May 30, 2024
a22cfa7
Fix story elm files
yoching May 30, 2024
d04e6d1
Update reference creation from otherNames
yoching Jun 10, 2024
7164ff1
Update to remove loading element before updating items
yoching Jun 21, 2024
6567574
Add `refResponse` to `WorkspaceItem Success`
yoching Jul 6, 2024
0097839
Update openItem member check to check both request and response refer…
yoching Jul 14, 2024
c0717e4
Update to use referenceMap for handling
yoching Aug 9, 2024
70ffd08
Clean some codes, remove unused codes
yoching Aug 9, 2024
a0925a1
Clean updateOneItem function
yoching Aug 9, 2024
4b5d50b
Merge branch 'main' into fix-multiple-definition
yoching Aug 9, 2024
27dd81b
Add cloud to storybook workspace
yoching Aug 9, 2024
d14745d
Add comment, rename
yoching Aug 9, 2024
e773d85
Remove refRequest from Success
yoching Aug 9, 2024
b2ed56f
Clean refRequest usages
yoching Aug 9, 2024
c70a68c
Add comment to decodeList
yoching Aug 9, 2024
60ffd78
Clean decodeTerms function
yoching Aug 9, 2024
fa5450e
Clean decodeTerms function
yoching Aug 15, 2024
0304465
Clean decodeTypes
yoching Aug 15, 2024
731144b
Merge branch 'clean-decoding' into fix-multiple-definition
yoching Aug 15, 2024
8d2fe1c
Remove decodeItem from WorkspaceItem (unused)
yoching Aug 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Code/Definition/Info.elm
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ type alias Info =


makeInfo : Reference -> FQN -> NEL.Nonempty FQN -> Info
makeInfo requestedRef suffixName allFqns =
makeInfo ref suffixName allFqns =
let
( namespace, otherNames ) =
namespaceAndOtherNames requestedRef suffixName allFqns
namespaceAndOtherNames ref suffixName allFqns
in
Info suffixName namespace otherNames

Expand Down
162 changes: 108 additions & 54 deletions src/Code/Workspace.elm
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ import Code.DefinitionSummaryTooltip as DefinitionSummaryTooltip
import Code.FullyQualifiedName exposing (FQN)
import Code.Hash as Hash
import Code.HashQualified as HQ
import Code.Workspace.WorkspaceItem as WorkspaceItem exposing (Item, WorkspaceItem, WorkspaceItemViewState)
import Code.Workspace.WorkspaceItem as WorkspaceItem exposing (ItemWithReferences, WorkspaceItem, WorkspaceItemViewState)
import Code.Workspace.WorkspaceItems as WorkspaceItems exposing (WorkspaceItems)
import Code.Workspace.WorkspaceMinimap as WorkspaceMinimap
import Dict exposing (Dict)
import Html exposing (Html, article, div, section)
import Html.Attributes exposing (class, id)
import Http
Expand All @@ -44,6 +45,7 @@ type alias Model =
, keyboardShortcut : KeyboardShortcut.Model
, workspaceItemViewState : WorkspaceItemViewState
, isMinimapToggled : Bool
, referenceMap : Dict String (List Reference) -- Map of refRequest to list refResponse, to handle multiple-responses case for one request
}


Expand All @@ -55,6 +57,7 @@ init config mRef =
, keyboardShortcut = KeyboardShortcut.init config.operatingSystem
, workspaceItemViewState = WorkspaceItem.viewState
, isMinimapToggled = False
, referenceMap = Dict.empty
}
in
case mRef of
Expand All @@ -71,7 +74,7 @@ init config mRef =

type Msg
= NoOp
| FetchItemFinished Reference (Result Http.Error Item)
| FetchItemFinished Reference (Result Http.Error (List ItemWithReferences))
| IsDocCropped Reference (Result Dom.Error Bool)
| Keydown KeyboardEvent
| KeyboardShortcutMsg KeyboardShortcut.Msg
Expand All @@ -91,62 +94,103 @@ type OutMsg
| ChangePerspectiveToSubNamespace (Maybe Reference) FQN


updateOneItem :
Reference
-> ItemWithReferences
-> ( ( WorkspaceItems, Dict String (List Reference) ), Cmd Msg )
-> ( ( WorkspaceItems, Dict String (List Reference) ), Cmd Msg )
updateOneItem refRequest { item, refResponse } ( ( workspaceItems, referenceMap ), aggCmd ) =
let
refReqeustKey =
Reference.toString refRequest

refResponseList =
referenceMap
|> Dict.get refReqeustKey
|> Maybe.withDefault []
|> (\list -> refResponse :: list)

updatedReferenceMap =
referenceMap
|> Dict.insert refReqeustKey refResponseList

cmd =
-- Docs items are always shown in full and never cropped
if WorkspaceItem.isDocItem item then
Cmd.none

else
isDocCropped refResponse

isDupe wi =
let
ref_ =
WorkspaceItem.reference wi

refEqs =
Reference.equals refResponse ref_

hashEqs =
wi
|> WorkspaceItem.hash
|> Maybe.map (Hash.equals (WorkspaceItem.itemHash item))
|> Maybe.withDefault False
in
(Reference.same refResponse ref_ && not refEqs) || (hashEqs && not refEqs)

-- In some cases (like using the back button between
-- perspectives) we try and fetch the same item twice, not
-- knowing we've fetched it before since one was by hash
-- and the other by name. If found to already be fetched,
-- we favor the newly fetched item and discard the old
deduped =
workspaceItems
|> WorkspaceItems.find isDupe
|> Maybe.map WorkspaceItem.reference
|> Maybe.map (WorkspaceItems.remove workspaceItems)
|> Maybe.withDefault workspaceItems

newWorkspaceItem =
WorkspaceItem.fromItem refResponse item
in
( ( WorkspaceItems.replaceOrPrependWithFocus deduped refResponse newWorkspaceItem
, updatedReferenceMap
)
, Cmd.batch [ aggCmd, cmd ]
)


update : Config -> ViewMode -> Msg -> Model -> ( Model, Cmd Msg, OutMsg )
update config viewMode msg ({ workspaceItems } as model) =
update config viewMode msg ({ workspaceItems, referenceMap } as model) =
case msg of
NoOp ->
( model, Cmd.none, None )

FetchItemFinished ref itemResult ->
FetchItemFinished refRequest itemResult ->
case itemResult of
Err e ->
( { model | workspaceItems = WorkspaceItems.replace workspaceItems ref (WorkspaceItem.Failure ref e) }
( { model | workspaceItems = WorkspaceItems.replace workspaceItems refRequest (WorkspaceItem.Failure refRequest e) }
, Cmd.none
, None
)

Ok i ->
Ok items ->
let
cmd =
-- Docs items are always shown in full and never cropped
if WorkspaceItem.isDocItem i then
Cmd.none
-- remove loading element (with `ref` used for request)
loadingRemoved =
WorkspaceItems.remove workspaceItems refRequest

else
isDocCropped ref

isDupe wi =
let
ref_ =
WorkspaceItem.reference wi

refEqs =
Reference.equals ref ref_

hashEqs =
wi
|> WorkspaceItem.hash
|> Maybe.map (Hash.equals (WorkspaceItem.itemHash i))
|> Maybe.withDefault False
in
(Reference.same ref ref_ && not refEqs) || (hashEqs && not refEqs)

-- In some cases (like using the back button between
-- perspectives) we try and fetch the same item twice, not
-- knowing we've fetched it before since one was by hash
-- and the other by name. If found to already be fetched,
-- we favor the newly fetched item and discard the old
deduped =
workspaceItems
|> WorkspaceItems.find isDupe
|> Maybe.map WorkspaceItem.reference
|> Maybe.map (WorkspaceItems.remove workspaceItems)
|> Maybe.withDefault workspaceItems

nextWorkspaceItems =
WorkspaceItems.replace deduped ref (WorkspaceItem.fromItem ref i)
-- update items with fetched result
( ( nextWorkspaceItems, nextReferenceMap ), cmd ) =
List.foldl (updateOneItem refRequest) ( ( loadingRemoved, referenceMap ), Cmd.none ) items
in
( { model | workspaceItems = nextWorkspaceItems }, cmd, None )
( { model
| workspaceItems = nextWorkspaceItems
, referenceMap = nextReferenceMap
}
, cmd
, None
)

IsDocCropped ref res ->
let
Expand Down Expand Up @@ -346,7 +390,7 @@ update config viewMode msg ({ workspaceItems } as model) =


type alias WithWorkspaceItems m =
{ m | workspaceItems : WorkspaceItems }
{ m | workspaceItems : WorkspaceItems, referenceMap : Dict String (List Reference) }


replaceWorkspaceItemReferencesWithHashOnly : Model -> Model
Expand Down Expand Up @@ -381,17 +425,24 @@ openReference config model relativeToRef ref =


openItem : Config -> WithWorkspaceItems m -> Maybe Reference -> Reference -> ( WithWorkspaceItems m, Cmd Msg )
openItem config ({ workspaceItems } as model) relativeToRef ref =
openItem config ({ workspaceItems, referenceMap } as model) relativeToRef ref =
-- We don't want to refetch or replace any already open definitions, but we
-- do want to focus and scroll to it (unless its already currently focused)
if WorkspaceItems.member workspaceItems ref then
if not (WorkspaceItems.isFocused workspaceItems ref) then
let
convertedRef =
referenceMap
|> Dict.get (Reference.toString ref)
|> Maybe.andThen List.head
|> Maybe.withDefault ref
in
if WorkspaceItems.member workspaceItems convertedRef then
if not (WorkspaceItems.isFocused workspaceItems convertedRef) then
let
nextWorkspaceItems =
WorkspaceItems.focusOn workspaceItems ref
WorkspaceItems.focusOn workspaceItems convertedRef
in
( { model | workspaceItems = nextWorkspaceItems }
, scrollToDefinition ref
, scrollToDefinition convertedRef
)

else
Expand All @@ -400,7 +451,7 @@ openItem config ({ workspaceItems } as model) relativeToRef ref =
else
let
toInsert =
WorkspaceItem.Loading ref
WorkspaceItem.Loading convertedRef

nextWorkspaceItems =
case relativeToRef of
Expand All @@ -411,7 +462,10 @@ openItem config ({ workspaceItems } as model) relativeToRef ref =
WorkspaceItems.insertWithFocusBefore workspaceItems r toInsert
in
( { model | workspaceItems = nextWorkspaceItems }
, Cmd.batch [ HttpApi.perform config.api (fetchDefinition config ref), scrollToDefinition ref ]
, Cmd.batch
[ HttpApi.perform config.api (fetchDefinition config convertedRef)
, scrollToDefinition convertedRef
]
)


Expand Down Expand Up @@ -531,7 +585,7 @@ handleKeyboardShortcut viewMode model shortcut =
-- EFFECTS


fetchDefinition : Config -> Reference -> ApiRequest Item Msg
fetchDefinition : Config -> Reference -> ApiRequest (List ItemWithReferences) Msg
fetchDefinition config ref =
let
endpoint =
Expand All @@ -542,7 +596,7 @@ fetchDefinition config ref =
in
endpoint
|> config.toApiEndpoint
|> HttpApi.toRequest (WorkspaceItem.decodeItem ref) (FetchItemFinished ref)
|> HttpApi.toRequest (WorkspaceItem.decodeList ref) (FetchItemFinished ref)


isDocCropped : Reference -> Cmd Msg
Expand Down
Loading
Loading