Skip to content

Commit

Permalink
Merge pull request #127 from oss-slu/inline_editors
Browse files Browse the repository at this point in the history
Adding Video Inline to Notes, Adjusting the size of images and videos, and Editor in Darkmode
  • Loading branch information
yashb196 authored Mar 17, 2024
2 parents e47372a + a82d003 commit 3d72665
Show file tree
Hide file tree
Showing 9 changed files with 611 additions and 133 deletions.
61 changes: 60 additions & 1 deletion __tests__/AddNoteRichEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ Enzyme.configure({ adapter: new Adapter() });

import React, { SetStateAction, useState } from 'react';
import { TouchableOpacity, Alert } from 'react-native';
import { render } from '@testing-library/react';

import AddNoteScreen from '../lib/screens/AddNoteScreen';
import { ThemeProvider } from '../lib/components/ThemeProvider';
import PhotoScroller from "../lib/components/photoScroller";
import { Media } from '../lib/models/media_class';
import moxios from 'moxios';
import AudioContainer from '../lib/components/audio';

import { addVideoToEditor } from '../lib/screens/AddNoteScreen';
import { getThumbnail } from '../lib/utils/S3_proxy';

beforeAll(() => {
jest.spyOn(console, 'log').mockImplementation(() => {});
jest.spyOn(console, 'error').mockImplementation(() => {});
Expand All @@ -31,6 +36,17 @@ jest.mock('../lib/components/ThemeProvider', () => ({
}),
}));

/*
jest.mock('../lib/screens/AddNoteScreen', () => ({
addVideoToEditor: jest.fn(),
}));
// Ensure you also mock getThumbnail if it's from another module
jest.mock('../lib/utils/S3_proxy', () => ({
getThumbnail: jest.fn(),
}));
*/

describe("AddNoteScreen", () => {
let wrapper;
let setNoteContentMock;
Expand Down Expand Up @@ -122,6 +138,49 @@ describe("AddNoteScreen", () => {
});
*/

/*
it("inserts video into the rich text editor", async () => {
const mockVideoUri = 'http://example.com/video.mp4';
const mockThumbnailUri = 'http://example.com/thumbnail.jpg';
// Set up your mocks with the desired behavior
getThumbnail.mockResolvedValue(mockThumbnailUri);
addVideoToEditor.mockImplementation(() => Promise.resolve()); // Assume it's async
// Assuming mockInsertHTML is a function you have access to, perhaps via global mocks
const mockInsertHTML = jest.fn();
global.richTextRef = {
current: {
insertHTML: mockInsertHTML,
},
};
// Act: Attempt to add video to editor
addVideoToEditor(mockVideoUri);
// Assertions
expect(getThumbnail).toHaveBeenCalledWith(mockVideoUri);
expect(addVideoToEditor).toHaveBeenCalledWith(mockVideoUri);
expect(mockInsertHTML).toHaveBeenCalled(); // This assumes insertHTML is called within addVideoToEditor
}); */

it('inserts video into the rich text editor', () => {
// Example video URI
const videoUri = 'http://example.com/video.mp4';

const richTextRef = { current: { insertHTML: jest.fn() } };

const insertVideoToEditor = (videoUri: string) => {
// Example: Inserting a video might involve wrapping the URI in a video tag
const videoHtml = `<video src="${videoUri}" controls></video>`;
richTextRef.current?.insertHTML(videoHtml);
};

// Call the function to insert the video
insertVideoToEditor(videoUri);

});
// Verify insertHTML was called with the correct HTML for the video
const expectedVideoHtml = `<video src="${videoUri}" controls></video>`;
expect(richTextRef.current.insertHTML).toHaveBeenCalledWith(expectedVideoHtml);
});
});
3 changes: 3 additions & 0 deletions lib/components/photoScroller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ const PhotoScroller = forwardRef(
setNewMedia,
active,
insertImageToEditor,
addVideoToEditor,
}: {
newMedia: Media[];
setNewMedia: React.Dispatch<React.SetStateAction<Media[]>>;
active: Boolean;
insertImageToEditor: Function;
addVideoToEditor: Function;
},
ref
) => {
Expand Down Expand Up @@ -118,6 +120,7 @@ const PhotoScroller = forwardRef(
duration: "0:00",
});
setNewMedia([...newMedia, newMediaItem]);
addVideoToEditor(uploadedUrl);
}
};

Expand Down
57 changes: 46 additions & 11 deletions lib/screens/AddNoteScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import * as Location from 'expo-location';
import { Note, AddNoteScreenProps } from "../../types";
import ToastMessage from 'react-native-toast-message';
import PhotoScroller from "../components/photoScroller";
import { getThumbnail } from "../utils/S3_proxy";
import { User } from "../models/user_class";
import { Ionicons } from "@expo/vector-icons";
import { Media, AudioType } from "../models/media_class";
Expand All @@ -30,6 +31,7 @@ import {
actions,
} from "react-native-pell-rich-editor";
import NotePageStyles from "../../styles/pages/NoteStyles";
import { useTheme } from "../components/ThemeProvider";

const user = User.getInstance();

Expand Down Expand Up @@ -57,6 +59,8 @@ const AddNoteScreen: React.FC<AddNoteScreenProps> = ({ navigation, route }) => {
longitude: number;
} | null>(null);

const { theme } = useTheme();

useEffect(() => {
const keyboardDidShowListener = Keyboard.addListener(
"keyboardDidShow",
Expand Down Expand Up @@ -130,12 +134,38 @@ const AddNoteScreen: React.FC<AddNoteScreenProps> = ({ navigation, route }) => {
}
};

// const onEditorContentSizeChange = (e) => {
// if (scrollViewRef.current) {
// scrollViewRef.current.scrollToEnd({ animated: true });
// }
// };
const addVideoToEditor = async (videoUri: string) => {
try {
// Fetch the thumbnail URI
const thumbnailUri = await getThumbnail(videoUri);

const videoHtml = `
<video width="320" height="240" controls poster="${thumbnailUri}" id="videoElement">
<source src="${videoUri}" type="video/mp4">
Your browser does not support the video tag.
</video>
<p><a href="${videoUri}" target="_blank">${videoUri}</a></p> <!-- Make the URI clickable -->
<script>
document.getElementById('videoElement').addEventListener('play', function(e) {
// Preventing the rich text editor from gaining focus when the video is played
e.preventDefault();
// Assuming you have a way to send a message to your React Native environment
window.ReactNativeWebView.postMessage('videoPlayed');
});
</script>
`;

richTextRef.current?.insertHTML(videoHtml);

setTimeout(() => {
if (scrollViewRef.current) {
scrollViewRef.current.scrollToEnd({ animated: true });
}
}, 500);
} catch (error) {
console.error("Error adding video with thumbnail: ", error);
}
}

const handleShareButtonPress = () => {
setIsPublished(!isPublished); // Toggle the share status
Expand Down Expand Up @@ -282,7 +312,7 @@ const AddNoteScreen: React.FC<AddNoteScreenProps> = ({ navigation, route }) => {
setIsLocation(false);
setIsTime(false);
}}
testID="images-icon"
data-testid="images-icon"
>
<Ionicons name="images-outline" size={30} color={NotePageStyles().saveText.color} />
</TouchableOpacity>
Expand Down Expand Up @@ -332,7 +362,7 @@ const AddNoteScreen: React.FC<AddNoteScreenProps> = ({ navigation, route }) => {
</TouchableOpacity>
</View>
<View style={NotePageStyles().container }>
<PhotoScroller active={viewMedia} newMedia={newMedia} setNewMedia={setNewMedia} insertImageToEditor={addImageToEditor} />
<PhotoScroller data-testid="photoScroller" active={viewMedia} newMedia={newMedia} setNewMedia={setNewMedia} insertImageToEditor={addImageToEditor} addVideoToEditor={addVideoToEditor}/>
{viewAudio && (
<AudioContainer newAudio={newAudio} setNewAudio={setNewAudio} />
)}
Expand Down Expand Up @@ -431,7 +461,7 @@ const AddNoteScreen: React.FC<AddNoteScreenProps> = ({ navigation, route }) => {
style={{ flex: 1 }}
keyboardVerticalOffset={Platform.OS === "ios" ? 60 : 20}
>
<View style={[NotePageStyles().container, { flex: 1 }]}>
<View style={[NotePageStyles().editorContainer, { flex: 1 }]}>
<ScrollView
nestedScrollEnabled={true}
showsVerticalScrollIndicator={false}
Expand All @@ -441,13 +471,14 @@ const AddNoteScreen: React.FC<AddNoteScreenProps> = ({ navigation, route }) => {
>
<RichEditor data-testid="RichEditor"
ref={(r) => (richTextRef.current = r)}
style={{...NotePageStyles().input, flex: 1, minHeight: 650 }}
style={[NotePageStyles().editor, {flex: 1, minHeight: 650 }]}
editorStyle={{
contentCSSText: `
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
color: theme.text;
`,
backgroundColor: theme.primaryColor,
color: theme.text,
}}
autoCorrect={true}
placeholder="Write your note here"
Expand All @@ -465,4 +496,8 @@ const AddNoteScreen: React.FC<AddNoteScreenProps> = ({ navigation, route }) => {

};

export default AddNoteScreen;
export default AddNoteScreen;

export function addVideoToEditor(mockVideoUri: string) {
throw new Error('Function not implemented.');
}
47 changes: 43 additions & 4 deletions lib/screens/EditNoteScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { Ionicons } from "@expo/vector-icons";
import { Note } from "../../types";
import PhotoScroller from "../components/photoScroller";
import { getThumbnail } from "../utils/S3_proxy";
import { User } from "../models/user_class";
import AudioContainer from "../components/audio";
import { Media, AudioType } from "../models/media_class";
Expand All @@ -26,6 +27,7 @@ import TimeWindow from "../components/time";
import { RichEditor, RichToolbar, actions } from "react-native-pell-rich-editor";
import NotePageStyles from "../../styles/pages/NoteStyles";
import ToastMessage from 'react-native-toast-message';
import { useTheme } from "../components/ThemeProvider";

const user = User.getInstance();

Expand Down Expand Up @@ -65,6 +67,7 @@ const EditNoteScreen: React.FC<EditNoteScreenProps> = ({
: null
);
const { height, width } = useWindowDimensions();
const { theme } = useTheme();

useEffect(() => {
const keyboardDidShowListener = Keyboard.addListener(
Expand Down Expand Up @@ -160,6 +163,39 @@ const EditNoteScreen: React.FC<EditNoteScreenProps> = ({
}
}, 500); // Adjust the delay as needed
};

const addVideoToEditor = async (videoUri: string) => {
try {
// Fetch the thumbnail URI
const thumbnailUri = await getThumbnail(videoUri);

const videoHtml = `
<video width="320" height="240" controls poster="${thumbnailUri}" id="videoElement">
<source src="${videoUri}" type="video/mp4">
Your browser does not support the video tag.
</video>
<p><a href="${videoUri}" target="_blank">${videoUri}</a></p> <!-- Make the URI clickable -->
<script>
document.getElementById('videoElement').addEventListener('play', function(e) {
// Preventing the rich text editor from gaining focus when the video is played
e.preventDefault();
// Assuming you have a way to send a message to your React Native environment
window.ReactNativeWebView.postMessage('videoPlayed');
});
</script>
`;

richTextRef.current?.insertHTML(videoHtml);

setTimeout(() => {
if (scrollViewRef.current) {
scrollViewRef.current.scrollToEnd({ animated: true });
}
}, 500);
} catch (error) {
console.error("Error adding video with thumbnail: ", error);
}
}

const handleSaveNote = async () => {
try {
Expand Down Expand Up @@ -194,7 +230,6 @@ const EditNoteScreen: React.FC<EditNoteScreenProps> = ({
<TouchableOpacity
style={NotePageStyles().topButtons}
onPress={owner ? handleSaveNote : () => navigation.goBack()}

>
<Ionicons name="arrow-back-outline" size={30} color={NotePageStyles().title.color} />
</TouchableOpacity>
Expand Down Expand Up @@ -246,6 +281,7 @@ const EditNoteScreen: React.FC<EditNoteScreenProps> = ({
newMedia={media}
setNewMedia={setMedia}
insertImageToEditor={addImageToEditor}
addVideoToEditor={addVideoToEditor}
/>
{viewAudio && (
<AudioContainer newAudio={newAudio} setNewAudio={setNewAudio} />
Expand Down Expand Up @@ -343,7 +379,7 @@ const EditNoteScreen: React.FC<EditNoteScreenProps> = ({
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{ flex: 1 }}
>
<View style={[NotePageStyles().container, { flex: 1 }]}>
<View style={[NotePageStyles().editorContainer, { flex: 1 }]}>
<ScrollView
nestedScrollEnabled={true}
showsVerticalScrollIndicator={false}
Expand All @@ -352,12 +388,15 @@ const EditNoteScreen: React.FC<EditNoteScreenProps> = ({
>
<RichEditor
ref={(r) => (richTextRef.current = r)}
style={{ ...NotePageStyles().input, flex: 1, minHeight: 650 }}
editorStyle={{
style={[NotePageStyles().editor, {flex: 1, minHeight: 650 }]}
editorStyle={
{
contentCSSText: `
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
`,
backgroundColor: theme.primaryColor,
color: theme.text,
}}
autoCorrect={true}
placeholder="Write your note here"
Expand Down
1 change: 1 addition & 0 deletions lib/screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ const HomeScreen: React.FC<HomeScreenProps> = ({ navigation, route }) => {
images:
item.media.map((mediaItem: { uri: any; }) => ({ uri: mediaItem.uri }))
};
console.log(formattedNote.description);
setSelectedNote(formattedNote);
setModalVisible(true);
}
Expand Down
Loading

0 comments on commit 3d72665

Please sign in to comment.