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

Swap Positions when pressed below mid screen #132

Open
tavaresluis00 opened this issue Feb 11, 2025 · 12 comments
Open

Swap Positions when pressed below mid screen #132

tavaresluis00 opened this issue Feb 11, 2025 · 12 comments

Comments

@tavaresluis00
Copy link

tavaresluis00 commented Feb 11, 2025

It works fine if I remove the ContextMenu.Preview, the problem is that in certain parts of the screen the Content swaps positions, so my reactions stay on correct place, but the group goes above the reactions

Image

@tavaresluis00 tavaresluis00 changed the title When Using ContextMenu.Auxiliary the preview assumes the width of the auxiliary Swap Positions when pressed below mid screen Feb 11, 2025
@tavaresluis00
Copy link
Author

@nandorojo if you could give quick help here

@nandorojo
Copy link
Owner

Hey can you please format this code better? I can't see it at all

@nandorojo
Copy link
Owner

Also please explain clearly what you expect vs what actually happens

@tavaresluis00
Copy link
Author

tavaresluis00 commented Feb 11, 2025

I expect the reactions to always show above the message and the menu with the reply etc below the message,

but when I press them and they are lower in the view they get on top of each other like on the screenshot

<ContextMenu.Content>
              <ContextMenu.Auxiliary
                alignmentHorizontal={isSent ? 'previewTrailing' : 'previewLeading'}
                anchorPosition="top"
                height={60}
                transitionConfigEntrance={{
                  transition: 'fade',
                }}
                transitionEntranceDelay={0.2}
              >
                {(menu) => (
                  <YStack
                    ai="center"
                    backgroundColor="#f2f2f2"
                    borderRadius="$3"
                    justifyContent="center"
                    padding="$2"
                    shadowColor="$black0"
                    shadowOffset={{ width: 0, height: 2 }}
                    shadowOpacity={0.2}
                    shadowRadius="$2"
                  >
                    <XStack backgroundColor="#f2f2f2">
                      {reactionOptions.map((reaction) => (
                        <Button
                          key={reaction}
                          unstyled
                          backgroundColor="transparent"
                          padding="$2"
                          size="$3"
                          onPress={() => {
                            handleReaction(reaction)
                            // 2) Then queue the state update immediately (or next frame)
                            requestAnimationFrame(() => {
                              menu.dismissMenu()
                            })
                          }}
                        >
                          {reaction}
                        </Button>
                      ))}
                      <Button
                        key="7"
                        unstyled
                        backgroundColor="transparent"
                        padding="$2"
                        size="$3"
                        onPress={() => {
                          menu.dismissMenu()
                        }}
                      >
                        +
                      </Button>
                    </XStack>
                  </YStack>
                )}
              </ContextMenu.Auxiliary>
                <ContextMenu.Item
                  key="pin"
                  onSelect={() => {
                    onPin?.({ id: message.id, isPinned })
                  }}
                >
                  <ContextMenu.ItemTitle>{isPinned ? 'Unpin' : 'Pin'}</ContextMenu.ItemTitle>
                  <ContextMenu.ItemIcon
                    androidIconName={isPinned ? 'pin-off' : 'pin'}
                    iosIconName={isPinned ? 'pin.slash.fill' : 'pin.fill'}
                  />
                </ContextMenu.Item>
                <ContextMenu.Item key="star" onSelect={handleStar}>
                  <ContextMenu.ItemTitle>{isStarred ? 'Unstar' : 'Star'}</ContextMenu.ItemTitle>
                  <ContextMenu.ItemIcon androidIconName="star" iosIconName="star.fill" />
                </ContextMenu.Item>
                <ContextMenu.Item
                  key="reply"
                  onSelect={() => {
                    onReply?.(message)
                  }}
                >
                  <ContextMenu.ItemTitle>Reply</ContextMenu.ItemTitle>
                  <ContextMenu.ItemIcon
                    androidIconName="reply"
                    iosIconName="arrowshape.turn.up.left"
                  />
                </ContextMenu.Item>
                <ContextMenu.Item
                  key="Copy"
                  onSelect={async () => {
                    await Clipboard.setStringAsync(message.content)
                    toast.show('Copied to Clipboard!')
                  }}
                >
                  <ContextMenu.ItemTitle>Copy</ContextMenu.ItemTitle>
                  <ContextMenu.ItemIcon androidIconName="content-copy" iosIconName="doc.on.doc" />
                </ContextMenu.Item>
                {isSent && (
                  <ContextMenu.Item key="Delete" onSelect={handleDelete}>
                    <ContextMenu.ItemTitle>Delete</ContextMenu.ItemTitle>
                    <ContextMenu.ItemIcon androidIconName="delete" iosIconName="trash" />
                  </ContextMenu.Item>
                )}
                {isSent && (
                  <ContextMenu.Item
                    key="Edit"
                    onSelect={() => {
                      handleEdit(message.content)
                    }}
                  >
                    <ContextMenu.ItemTitle>Edit</ContextMenu.ItemTitle>
                    <ContextMenu.ItemIcon androidIconName="edit" iosIconName="pencil" />
                  </ContextMenu.Item>
                )}
                <ContextMenu.Item key="Info">
                  <ContextMenu.ItemTitle>Info</ContextMenu.ItemTitle>
                  <ContextMenu.ItemIcon androidIconName="info-outline" iosIconName="info.circle" />
                </ContextMenu.Item>
            </ContextMenu.Content>
          </ContextMenu.Root>

@tavaresluis00
Copy link
Author

Image

and should be like this always

@nandorojo
Copy link
Owner

What if you try these props? (You’ll need to rename some)

verticalAnchorPosition: 'automatic',
            horizontalAlignment: isMe ? 'targetTrailing' : 'targetLeading',
            marginVerticalInner: 10,
            anchorPosition: 'automatic',
            transitionConfigEntrance: {
              mode: 'syncedToMenuEntranceTransition',
              shouldAnimateSize: true,
            },
            transitionExitPreset: {
              mode: 'zoomAndSlide',
              zoomOffset: 0.8,
              slideOffset: -20,
            },

@tavaresluis00
Copy link
Author

If I change to automatic they still swap positions but dont overlap

The reaction just stays below the message and vice-versa

@tavaresluis00
Copy link
Author

And hw wont even run If I put some of the props you gave me

@tavaresluis00
Copy link
Author

@nandorojo

@nandorojo
Copy link
Owner

Hey please don't frequently tag here, keep in mind it's open source

@nandorojo
Copy link
Owner

Okay so I think the issue here is that iOS automatically does this for you. I don't think there's a way around it actually...

@nandorojo
Copy link
Owner

I wonder if there is an example of what you want working on the upstream react-native-ios-context-menu library...

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

2 participants