@rpg-engine/long-bow 0.6.85 → 0.6.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.6.85",
3
+ "version": "0.6.87",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -86,6 +86,7 @@
86
86
  "@rpg-engine/shared": "^0.9.52",
87
87
  "dayjs": "^1.11.2",
88
88
  "font-awesome": "^4.7.0",
89
+ "framer-motion": "^11.3.31",
89
90
  "fs-extra": "^10.1.0",
90
91
  "lodash": "^4.17.21",
91
92
  "lodash-es": "^4.17.21",
@@ -10,6 +10,7 @@ import styled from 'styled-components';
10
10
  import { uiColors } from '../../constants/uiColors';
11
11
  import { uiFonts } from '../../constants/uiFonts';
12
12
  import { Chat, IStyles } from '../Chat/Chat';
13
+ import { Ellipsis } from '../shared/Ellipsis';
13
14
  import { SearchCharacter } from './SearchCharacter';
14
15
 
15
16
  export type PrivateChatCharacter = Pick<ICharacter, '_id' | 'name'>;
@@ -81,13 +82,13 @@ export const ChatRevamp = ({
81
82
  };
82
83
 
83
84
  return (
84
- <>
85
+ <ChatContainer>
85
86
  <TabContainer>
86
87
  {tabs.map((tab, index) => (
87
88
  <Tab
88
89
  key={`${tab.label}_${index}`}
89
90
  active={tab.id === activeTab}
90
- onPointerDown={() => onChangeTab(tab.id)}
91
+ onClick={() => onChangeTab(tab.id)}
91
92
  >
92
93
  {tab.label}
93
94
  </Tab>
@@ -97,56 +98,63 @@ export const ChatRevamp = ({
97
98
  width={styles?.width || '80%'}
98
99
  height={styles?.height || 'auto'}
99
100
  >
100
- <RecentChatTabContainer isPrivate={isPrivate} isOpen={showRecentChats}>
101
- <RecentChatTopBar isOpen={showRecentChats}>
102
- <BurgerIconContainer
103
- onPointerDown={() => setShowRecentChats(t => !t)}
104
- hasUnseenMessages={unseenMessageCharacterIds?.length > 0 || false}
105
- >
106
- <BurgerLineIcon></BurgerLineIcon>
107
- <BurgerLineIcon></BurgerLineIcon>
108
- <BurgerLineIcon></BurgerLineIcon>
109
- </BurgerIconContainer>
110
- {showRecentChats && (
111
- <SearchButton onPointerDown={() => showSearchCharacterUI()}>
112
- <RxMagnifyingGlass size={16} color={uiColors.white} />
113
- </SearchButton>
114
- )}
115
- </RecentChatTopBar>
101
+ {isPrivate && (
102
+ <RecentChatTabContainer
103
+ isPrivate={isPrivate}
104
+ isOpen={showRecentChats}
105
+ >
106
+ <RecentChatTopBar isOpen={showRecentChats}>
107
+ <BurgerIconContainer
108
+ onClick={() => setShowRecentChats(t => !t)}
109
+ hasUnseenMessages={
110
+ unseenMessageCharacterIds?.length > 0 || false
111
+ }
112
+ >
113
+ <BurgerLineIcon></BurgerLineIcon>
114
+ <BurgerLineIcon></BurgerLineIcon>
115
+ <BurgerLineIcon></BurgerLineIcon>
116
+ </BurgerIconContainer>
117
+ {showRecentChats && (
118
+ <SearchButton onClick={() => showSearchCharacterUI()}>
119
+ <RxMagnifyingGlass size={16} color={uiColors.white} />
120
+ </SearchButton>
121
+ )}
122
+ </RecentChatTopBar>
116
123
 
117
- <RecentChatLogContainer isOpen={showRecentChats}>
118
- {recentChatCharacters?.map(character => (
119
- <ListElementContainer key={character._id}>
120
- <ListElement
121
- active={character._id === recentSelectedChatCharacterId}
122
- onPointerDown={() =>
123
- handlePreviousChatCharacterClick(character)
124
- }
125
- >
126
- <StatusDot
127
- isUnseen={
128
- unseenMessageCharacterIds?.includes(character._id) ||
129
- false
130
- }
131
- />
132
- {character.name}
133
- </ListElement>
134
- <CloseButton
135
- onPointerDown={() => onRemoveRecentChatCharacter?.(character)}
136
- >
137
- <RxCross2 size={16} />
138
- </CloseButton>
139
- </ListElementContainer>
140
- ))}
141
- </RecentChatLogContainer>
142
- </RecentChatTabContainer>
124
+ <RecentChatLogContainer isOpen={showRecentChats}>
125
+ {recentChatCharacters?.map(character => (
126
+ <ListElementContainer key={character._id}>
127
+ <ListElement
128
+ active={character._id === recentSelectedChatCharacterId}
129
+ onClick={() => handlePreviousChatCharacterClick(character)}
130
+ >
131
+ <StatusDot
132
+ isUnseen={
133
+ unseenMessageCharacterIds?.includes(character._id) ||
134
+ false
135
+ }
136
+ />
137
+ <Ellipsis maxLines={1} maxWidth="140px">
138
+ {character.name}
139
+ </Ellipsis>
140
+ </ListElement>
141
+ <CloseButton
142
+ onClick={() => onRemoveRecentChatCharacter?.(character)}
143
+ >
144
+ <RxCross2 size={16} />
145
+ </CloseButton>
146
+ </ListElementContainer>
147
+ ))}
148
+ </RecentChatLogContainer>
149
+ </RecentChatTabContainer>
150
+ )}
143
151
  {isPrivate && searchCharacterUI ? (
144
152
  <SearchCharacter
145
153
  onFocus={onFocus}
146
154
  onBlur={onBlur}
147
155
  onChangeCharacterName={onChangeCharacterName}
148
156
  styles={styles}
149
- recentCharacters={privateChatCharacters}
157
+ recentCharacters={privateChatCharacters as ICharacter[]}
150
158
  hideSearchCharacterUI={hideSearchCharacterUI}
151
159
  onCharacterClick={onCharacterClick}
152
160
  />
@@ -168,10 +176,18 @@ export const ChatRevamp = ({
168
176
  />
169
177
  )}
170
178
  </PrivateChatContainer>
171
- </>
179
+ </ChatContainer>
172
180
  );
173
181
  };
174
182
 
183
+ const ChatContainer = styled.div`
184
+ display: flex;
185
+ flex-direction: column;
186
+ gap: 10px;
187
+ max-width: 1200px;
188
+ margin: 0 auto;
189
+ `;
190
+
175
191
  const TabContainer = styled.div`
176
192
  width: 100%;
177
193
  display: flex;
@@ -185,15 +201,20 @@ const Tab = styled.button<{ active: boolean }>`
185
201
  all: unset;
186
202
  padding: 0.6rem;
187
203
  font-size: 0.8rem;
188
-
189
204
  border-radius: 5px 5px 0 0;
190
205
  border-width: 0.25rem 0.25rem 0 0.25rem;
191
206
  border-style: solid;
192
207
  border-color: ${props => (props.active ? '#c65102' : uiColors.gray)};
193
-
194
208
  background-color: ${props =>
195
209
  props.active ? uiColors.orange : 'transparent'};
196
210
  color: ${props => (props.active ? 'white' : uiColors.raisinBlack)};
211
+ transition: all 0.3s ease;
212
+ cursor: pointer;
213
+
214
+ &:hover {
215
+ background-color: ${props =>
216
+ props.active ? uiColors.orange : uiColors.lightGray};
217
+ }
197
218
  `;
198
219
 
199
220
  const PrivateChatContainer = styled.div<{ width: string; height: string }>`
@@ -204,6 +225,8 @@ const PrivateChatContainer = styled.div<{ width: string; height: string }>`
204
225
  height: auto;
205
226
  display: flex;
206
227
  gap: 10px;
228
+ border-radius: 0 0 10px 10px;
229
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
207
230
  `;
208
231
 
209
232
  const RecentChatTabContainer = styled.div<{
@@ -292,7 +315,8 @@ const ListElementContainer = styled.div`
292
315
  const ListElement = styled.button<{ active: boolean }>`
293
316
  margin: 0.5rem 0 !important;
294
317
  font-size: ${uiFonts.size.small} !important;
295
- padding: 2px;
318
+ padding: 8px;
319
+ border-radius: 4px;
296
320
  all: unset;
297
321
  color: ${props => (props.active ? uiColors.yellow : uiColors.white)};
298
322
  width: 100%;
@@ -300,9 +324,10 @@ const ListElement = styled.button<{ active: boolean }>`
300
324
  display: flex;
301
325
  align-items: center;
302
326
  gap: 4px;
327
+ transition: all 0.2s ease;
303
328
 
304
329
  &:hover {
305
- color: #ff0;
330
+ background-color: rgba(255, 255, 255, 0.1);
306
331
  }
307
332
  `;
308
333
 
@@ -323,6 +348,12 @@ const CloseButton = styled.button`
323
348
  transition: all 0.2s ease-in-out;
324
349
  background-color: ${uiColors.red};
325
350
  color: ${uiColors.white};
351
+ border-radius: 50%;
352
+ padding: 4px;
353
+ display: flex;
354
+ align-items: center;
355
+ justify-content: center;
356
+
326
357
  &:hover {
327
358
  background-color: ${uiColors.white};
328
359
  color: ${uiColors.red};
@@ -1,23 +1,23 @@
1
+ import { ICharacter } from '@rpg-engine/shared/dist/types/character.types';
1
2
  import React, { useEffect, useRef, useState } from 'react';
2
- import { RxMagnifyingGlass } from 'react-icons/rx';
3
+ import { RxCross2, RxMagnifyingGlass } from 'react-icons/rx';
3
4
  import styled from 'styled-components';
4
5
  import { uiColors } from '../../constants/uiColors';
5
6
  import { uiFonts } from '../../constants/uiFonts';
6
7
  import { IStyles } from '../Chat/Chat';
7
- import { Column } from '../shared/Column';
8
- import type { PrivateChatCharacter } from './ChatRevamp';
8
+ import { Ellipsis } from '../shared/Ellipsis';
9
9
 
10
10
  interface ISearchCharacterProps {
11
11
  onFocus?: () => void;
12
12
  onBlur?: () => void;
13
13
  onChangeCharacterName: (characterName: string) => void;
14
14
  styles?: IStyles;
15
- recentCharacters?: PrivateChatCharacter[];
16
- onCharacterClick?: (character: PrivateChatCharacter) => void;
15
+ recentCharacters?: ICharacter[];
16
+ onCharacterClick?: (character: ICharacter) => void;
17
17
  hideSearchCharacterUI: () => void;
18
18
  }
19
19
 
20
- export const SearchCharacter = ({
20
+ export const SearchCharacter: React.FC<ISearchCharacterProps> = ({
21
21
  onChangeCharacterName,
22
22
  onBlur,
23
23
  onFocus,
@@ -25,143 +25,241 @@ export const SearchCharacter = ({
25
25
  hideSearchCharacterUI,
26
26
  onCharacterClick,
27
27
  styles = {
28
- textColor: '#c65102',
29
- buttonColor: '#005b96',
30
- buttonBackgroundColor: 'rgba(0,0,0,.2)',
31
- width: '80%',
28
+ textColor: uiColors.white,
29
+ buttonColor: uiColors.orange,
30
+ buttonBackgroundColor: uiColors.darkGray,
31
+ width: '100%',
32
32
  height: 'auto',
33
33
  },
34
- }: ISearchCharacterProps) => {
34
+ }) => {
35
35
  const [characterName, setCharacterName] = useState('');
36
+ const [isFocused, setIsFocused] = useState(false);
36
37
  const searchCharacterRef = useRef<HTMLInputElement>(null);
37
38
 
38
39
  useEffect(() => {
39
- const timer = setTimeout(() => {
40
- if (searchCharacterRef.current) {
41
- searchCharacterRef.current.focus();
42
- }
43
- }, 100);
44
-
45
- return () => clearTimeout(timer);
40
+ if (searchCharacterRef.current) {
41
+ searchCharacterRef.current.focus();
42
+ }
46
43
  }, []);
47
44
 
48
- const handleSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
45
+ const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
49
46
  event.preventDefault();
50
- if (!characterName || characterName.trim() === '') return;
47
+ if (!characterName.trim()) return;
51
48
  onChangeCharacterName(characterName);
52
49
  };
53
50
 
54
- const handleCharacterClick = (
55
- character: PrivateChatCharacter
56
- ) => {
51
+ const handleCharacterClick = (character: ICharacter) => {
57
52
  if (!onCharacterClick) return;
58
53
  setCharacterName('');
59
54
  onCharacterClick(character);
60
55
  hideSearchCharacterUI();
61
56
  };
62
57
 
58
+ const handleFocus = () => {
59
+ setIsFocused(true);
60
+ onFocus?.();
61
+ };
62
+
63
+ const handleBlur = () => {
64
+ setIsFocused(false);
65
+ onBlur?.();
66
+ };
67
+
63
68
  return (
64
- <SearchContainer>
69
+ <SearchContainer width={styles.width || 'auto'}>
65
70
  <Form onSubmit={handleSubmit}>
66
- <Column flex={70}>
71
+ <InputWrapper isFocused={isFocused}>
72
+ <SearchIcon>
73
+ <RxMagnifyingGlass />
74
+ </SearchIcon>
67
75
  <TextField
68
76
  value={characterName}
69
77
  ref={searchCharacterRef}
70
- id="characterName"
71
- name='characterName'
72
78
  onChange={e => {
73
79
  setCharacterName(e.target.value);
74
80
  onChangeCharacterName(e.target.value);
75
81
  }}
76
- placeholder='Search for a character...'
77
- height={20}
82
+ placeholder="Search for a character..."
78
83
  type="text"
79
84
  autoComplete="off"
80
- onFocus={onFocus}
81
- onBlur={onBlur}
82
- onPointerDown={onFocus}
83
- />
84
- </Column>
85
- <Column justifyContent="flex-end">
86
- <SearchButton
87
- type='submit'
88
- buttonColor={styles?.buttonColor || '#005b96'}
89
- buttonBackgroundColor={
90
- styles?.buttonBackgroundColor || 'rgba(0,0,0,.5)'
91
- }
92
- id="chat-send-button"
93
- style={{ borderRadius: '20%' }}
94
- >
95
- <RxMagnifyingGlass size={15} />
96
- </SearchButton>
97
- </Column>
85
+ onFocus={handleFocus}
86
+ onBlur={handleBlur}
87
+ />
88
+ {characterName && (
89
+ <ClearButton onClick={() => setCharacterName('')} type="button">
90
+ <RxCross2 />
91
+ </ClearButton>
92
+ )}
93
+ </InputWrapper>
94
+ <SearchButton
95
+ type="submit"
96
+ buttonColor={styles.buttonColor!}
97
+ buttonBackgroundColor={styles.buttonBackgroundColor!}
98
+ >
99
+ Search
100
+ </SearchButton>
98
101
  </Form>
99
102
 
100
103
  {recentCharacters && recentCharacters.length > 0 && (
101
- <ListContainer>
102
- {recentCharacters.map(character => (
103
- <ListElement onPointerDown={() => handleCharacterClick(character)} key={character._id}>
104
- {character.name}
105
- </ListElement>
106
- ))}
107
- </ListContainer>
104
+ <ResultsContainer>
105
+ <ResultsTitle>Recent Characters</ResultsTitle>
106
+ <ResultsList>
107
+ {recentCharacters.map(character => (
108
+ <ResultItem
109
+ key={character._id}
110
+ onClick={() => handleCharacterClick(character)}
111
+ >
112
+ <CharacterAvatar
113
+ src={character.textureKey || '/default-avatar.png'}
114
+ alt={character.name}
115
+ />
116
+ <CharacterInfo>
117
+ <CharacterName>
118
+ <Ellipsis maxLines={1} maxWidth="150px">
119
+ {character.name}
120
+ </Ellipsis>
121
+ </CharacterName>
122
+ <CharacterDescription>
123
+ <Ellipsis
124
+ maxLines={1}
125
+ maxWidth="150px"
126
+ >{`Class: ${character.class}, Level: ${character.skills.level}`}</Ellipsis>
127
+ </CharacterDescription>
128
+ </CharacterInfo>
129
+ </ResultItem>
130
+ ))}
131
+ </ResultsList>
132
+ </ResultsContainer>
108
133
  )}
109
- </SearchContainer>
134
+ </SearchContainer>
110
135
  );
111
136
  };
112
137
 
113
-
114
- interface IButtonProps {
115
- buttonColor: string;
116
- buttonBackgroundColor: string;
117
- }
118
-
119
- const SearchContainer = styled.div`
120
- width: 100%;
121
- `
138
+ const SearchContainer = styled.div<{ width: string }>`
139
+ width: ${({ width }) => width};
140
+ max-width: 600px;
141
+ margin: 0 auto;
142
+ `;
122
143
 
123
144
  const Form = styled.form`
124
145
  display: flex;
125
- width: 100%;
126
- justify-content: center;
146
+ gap: 10px;
147
+ margin-bottom: 20px;
148
+ `;
149
+
150
+ const InputWrapper = styled.div<{ isFocused: boolean }>`
151
+ position: relative;
152
+ flex-grow: 1;
153
+ display: flex;
127
154
  align-items: center;
155
+ background-color: ${uiColors.raisinBlack};
156
+ border-radius: 24px;
157
+ padding: 8px 16px;
158
+ transition: all 0.3s ease;
159
+ box-shadow: ${({ isFocused }) =>
160
+ isFocused ? `0 0 0 2px ${uiColors.orange}` : 'none'};
161
+ `;
162
+
163
+ const SearchIcon = styled.span`
164
+ color: ${uiColors.gray};
165
+ margin-right: 8px;
128
166
  `;
129
167
 
130
168
  const TextField = styled.input`
131
169
  width: 100%;
132
- background-color: rgba(0, 0, 0, 0.25) !important;
133
- border: none !important;
134
- max-height: 28px !important;
170
+ background-color: transparent;
171
+ border: none;
172
+ color: ${uiColors.white};
173
+ font-size: ${uiFonts.size.medium};
174
+ outline: none;
175
+
176
+ &::placeholder {
177
+ color: ${uiColors.gray};
178
+ }
135
179
  `;
136
180
 
137
- const SearchButton = styled.button<IButtonProps>`
138
- color: ${({ buttonColor }) => buttonColor};
139
- background-color: ${({ buttonBackgroundColor }) => buttonBackgroundColor};
140
- width: 28px;
141
- height: 28px;
142
- border: none !important;
181
+ const ClearButton = styled.button`
182
+ background: none;
183
+ border: none;
184
+ color: ${uiColors.gray};
185
+ cursor: pointer;
186
+ padding: 0;
187
+ display: flex;
188
+ align-items: center;
189
+ justify-content: center;
143
190
  `;
144
191
 
145
- const ListContainer = styled.ul`
192
+ const SearchButton = styled.button<{
193
+ buttonColor: string;
194
+ buttonBackgroundColor: string;
195
+ }>`
196
+ background-color: ${({ buttonBackgroundColor }) => buttonBackgroundColor};
197
+ color: ${({ buttonColor }) => buttonColor};
146
198
  border: none;
147
- overflow-y: scroll;
148
- list-style: none;
199
+ border-radius: 24px;
200
+ padding: 8px 16px;
201
+ font-size: ${uiFonts.size.medium};
202
+ font-weight: bold;
203
+ cursor: pointer;
204
+ transition: all 0.3s ease;
205
+
206
+ &:hover {
207
+ background-color: ${uiColors.orange};
208
+ color: ${uiColors.white};
209
+ }
210
+ `;
211
+
212
+ const ResultsContainer = styled.div`
213
+ background-color: ${uiColors.raisinBlack};
214
+ border-radius: 8px;
215
+ padding: 16px;
216
+ `;
217
+
218
+ const ResultsTitle = styled.h3`
219
+ color: ${uiColors.white};
220
+ font-size: ${uiFonts.size.medium};
221
+ margin-bottom: 12px;
222
+ `;
223
+
224
+ const ResultsList = styled.ul`
225
+ list-style-type: none;
149
226
  padding: 0;
227
+ margin: 0;
150
228
  `;
151
229
 
152
- const ListElement = styled.li`
153
- margin: 0.5rem 0 !important;
154
- font-size: ${uiFonts.size.small};
155
- padding: 0.5rem 2px;
230
+ const ResultItem = styled.li`
231
+ display: flex;
232
+ align-items: center;
233
+ padding: 8px;
234
+ cursor: pointer;
235
+ border-radius: 4px;
236
+ transition: all 0.2s ease;
156
237
 
157
238
  &:hover {
158
- color: #ff0;
159
239
  background-color: ${uiColors.darkGray};
160
240
  }
241
+ `;
161
242
 
162
- button {
163
- all: unset;
164
- }
243
+ const CharacterAvatar = styled.img`
244
+ width: 40px;
245
+ height: 40px;
246
+ border-radius: 50%;
247
+ margin-right: 12px;
248
+ object-fit: cover;
249
+ `;
250
+
251
+ const CharacterInfo = styled.div`
252
+ flex-grow: 1;
165
253
  `;
166
254
 
255
+ const CharacterName = styled.div`
256
+ color: ${uiColors.white};
257
+ font-size: ${uiFonts.size.medium};
258
+ font-weight: bold;
259
+ margin-bottom: 4px;
260
+ `;
167
261
 
262
+ const CharacterDescription = styled.div`
263
+ color: ${uiColors.gray};
264
+ font-size: ${uiFonts.size.small};
265
+ `;
@@ -1,5 +1,5 @@
1
1
  import { ISpell } from '@rpg-engine/shared';
2
- import React, { useState } from 'react';
2
+ import React, { useRef, useState } from 'react';
3
3
  import { MobileSpellTooltip } from './MobileSpellTooltip';
4
4
  import { MagicTooltip } from './SpellTooltip';
5
5
 
@@ -7,15 +7,32 @@ interface ISpellInfoWrapperProps {
7
7
  spell: ISpell;
8
8
  children: React.ReactNode;
9
9
  scale?: number;
10
+ holdTouchDuration?: number; // New prop for hold touch duration
10
11
  }
11
12
 
12
13
  export const SpellInfoWrapper: React.FC<ISpellInfoWrapperProps> = ({
13
14
  children,
14
15
  spell,
15
16
  scale,
17
+ holdTouchDuration = 500, // Default hold duration to 500ms
16
18
  }) => {
17
19
  const [isTooltipVisible, setIsTooltipVisible] = useState(false);
18
20
  const [isTooltipMobileVisible, setIsTooltipMobileVisible] = useState(false);
21
+ const touchTimeoutRef = useRef<NodeJS.Timeout | null>(null);
22
+
23
+ const handleTouchStart = () => {
24
+ touchTimeoutRef.current = setTimeout(() => {
25
+ setIsTooltipMobileVisible(true);
26
+ setIsTooltipVisible(false);
27
+ }, holdTouchDuration);
28
+ };
29
+
30
+ const handleTouchEnd = () => {
31
+ if (touchTimeoutRef.current) {
32
+ clearTimeout(touchTimeoutRef.current);
33
+ touchTimeoutRef.current = null;
34
+ }
35
+ };
19
36
 
20
37
  return (
21
38
  <div
@@ -23,10 +40,8 @@ export const SpellInfoWrapper: React.FC<ISpellInfoWrapperProps> = ({
23
40
  if (!isTooltipMobileVisible) setIsTooltipVisible(true);
24
41
  }}
25
42
  onMouseLeave={setIsTooltipVisible.bind(null, false)}
26
- onTouchEnd={() => {
27
- setIsTooltipMobileVisible(true);
28
- setIsTooltipVisible(false);
29
- }}
43
+ onTouchStart={handleTouchStart}
44
+ onTouchEnd={handleTouchEnd}
30
45
  >
31
46
  {children}
32
47
 
@@ -45,4 +60,4 @@ export const SpellInfoWrapper: React.FC<ISpellInfoWrapperProps> = ({
45
60
  )}
46
61
  </div>
47
62
  );
48
- };
63
+ };
@@ -206,7 +206,7 @@ const tabsMock = [
206
206
  ];
207
207
 
208
208
  const recentPrivateChatCharactersMock = [
209
- { _id: 'someid', name: 'Guilherme' },
209
+ { _id: 'someid', name: 'Guilhermexxxxxxxxxxxx' },
210
210
  { _id: 'someid2', name: 'Guilherme2' },
211
211
  ];
212
212