diff --git a/README.md b/README.md index 4aecec9..a851e75 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +Artifical Chat is an app to explore the wonders of conversational AI using React Native for Windows to build the user experience. The goal is to handle not just plain text but rich markdown documents, code, and faciliate image generation as well. + +![image](https://user-images.githubusercontent.com/26607885/233441056-39033d3c-3420-4c31-b7db-ca39944fc00e.png) + # Setup 1. Install all dependencies per [RNW Dependencies](https://microsoft.github.io/react-native-windows/docs/rnw-dependencies) 1. `yarn` @@ -101,5 +105,6 @@ The app's settings are handled by a `SettingsContext` object, which has dialog U - Syntax Highlighting via [react-native-syntax-highlighter](https://github.com/conorhastings/react-native-syntax-highlighter) - Dependency patching via [patch-package](https://github.com/ds300/patch-package) - Storage via [react-native-async-storage](https://github.com/react-native-async-storage/async-storage) -- Markdown rendering via [react-native-markdown-display](https://github.com/iamacup/react-native-markdown-display) -- Button, Checkbox, Link via [@fluentui/react-native](https://github.com/microsoft/fluentui-react-native) \ No newline at end of file +- Markdown rendering via [react-native-markdown-display-updated](https://github.com/willmac321/react-native-markdown-display) +- Dialogs via [react-native-content-dialog](https://github.com/chrisglein/react-native-content-dialog) +- Button, Checkbox, Link via [@fluentui/react-native](https://github.com/microsoft/fluentui-react-native) diff --git a/package.json b/package.json index ef8f380..59191a9 100644 --- a/package.json +++ b/package.json @@ -14,15 +14,16 @@ "dependencies": { "@fluentui/react-native": "^0.36.20", "@react-native-async-storage/async-storage": "^1.17.11", - "@react-native-clipboard/clipboard": "^1.11.2", - "@react-native-picker/picker": "^2.2.1", + "@react-native-clipboard/clipboard": "^1.12.1", + "@react-native-picker/picker": "^2.5.1", "patch-package": "^6.5.1", "postinstall-postinstall": "^2.1.0", "react": "18.2.0", "react-native": "0.71.0", - "react-native-markdown-display": "^7.0.0-alpha.2", - "react-native-svg": "^14.0.0", + "react-native-content-dialog": "^0.2.0", + "react-native-markdown-display-updated": "^7.0.0", "react-native-syntax-highlighter": "^2.1.0", + "react-native-svg": "^14.0.0", "react-native-windows": "0.71.1" }, "devDependencies": { diff --git a/patches/@react-native-clipboard+clipboard+1.11.2.patch b/patches/@react-native-clipboard+clipboard+1.11.2.patch deleted file mode 100644 index db1c6dc..0000000 --- a/patches/@react-native-clipboard+clipboard+1.11.2.patch +++ /dev/null @@ -1,86 +0,0 @@ -diff --git a/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.cpp b/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.cpp -index d566a46..0b7ef28 100644 ---- a/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.cpp -+++ b/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.cpp -@@ -8,7 +8,7 @@ namespace NativeClipboard { - if (dataPackageView.Contains(datatransfer::StandardDataFormats::Text())) { - dataPackageView.GetTextAsync().Completed([promise, dataPackageView](IAsyncOperation info, AsyncStatus status) { - if (status == AsyncStatus::Completed) { -- auto text = Microsoft::Common::Unicode::Utf16ToUtf8(info.GetResults()); -+ auto text = winrt::to_string(info.GetResults()); - promise.Resolve(text); - } - else { -@@ -22,8 +22,23 @@ namespace NativeClipboard { - - void ClipboardModule::SetString(std::string const& str) noexcept - { -- datatransfer::DataPackage dataPackage{}; -- dataPackage.SetText(Microsoft::Common::Unicode::Utf8ToUtf16(str)); -- datatransfer::Clipboard::SetContent(dataPackage); -+ _context.UIDispatcher().Post([str](){ -+ datatransfer::DataPackage dataPackage{}; -+ dataPackage.SetText(winrt::to_hstring(str)); -+ datatransfer::Clipboard::SetContent(dataPackage); -+ }); -+ } -+ -+ void ClipboardModule::AddListener(std::string const& event) noexcept -+ { -+ _listenerCount++; -+ } -+ -+ void ClipboardModule::RemoveListeners(int count) noexcept -+ { -+ _listenerCount--; -+ if (_listenerCount == 0) { -+ // Disconnect any native eventing here -+ } - } - } -\ No newline at end of file -diff --git a/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.h b/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.h -index fdf68cf..7cf8566 100644 ---- a/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.h -+++ b/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.h -@@ -16,11 +16,26 @@ namespace NativeClipboard { - REACT_MODULE(ClipboardModule, L"RNCClipboard"); - struct ClipboardModule - { -+ REACT_INIT(Initialize); -+ void Initialize(const winrt::Microsoft::ReactNative::ReactContext& reactContext) noexcept -+ { -+ _context = reactContext; -+ } - - REACT_METHOD(GetString, L"getString"); - void GetString(React::ReactPromise&& result) noexcept; - - REACT_METHOD(SetString, L"setString"); - void SetString(std::string const& str) noexcept; -+ -+ REACT_METHOD(AddListener, L"addListener"); -+ void AddListener(std::string const& event) noexcept; -+ -+ REACT_METHOD(RemoveListeners, L"removeListeners"); -+ void RemoveListeners(int count) noexcept; -+ -+ private: -+ ReactContext _context; -+ int _listenerCount = 0; - }; - } -\ No newline at end of file -diff --git a/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.vcxproj b/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.vcxproj -index 4904b68..bf7dcfa 100644 ---- a/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.vcxproj -+++ b/node_modules/@react-native-clipboard/clipboard/windows/Clipboard/Clipboard.vcxproj -@@ -14,7 +14,7 @@ - true - Windows Store - 10.0 -- 10.0.18362.0 -+ 10.0 - 10.0.17134.0 - - diff --git a/src/About.tsx b/src/About.tsx index 9a165d1..d51a153 100644 --- a/src/About.tsx +++ b/src/About.tsx @@ -6,7 +6,7 @@ import { } from 'react-native'; import {Hyperlink} from './Controls'; import { - DialogFrame, + ContentDialog, } from './Popups'; import {StylesContext} from './Styles'; import VersionInfo from './NativeVersionInfo' @@ -19,10 +19,11 @@ function AboutPopup({show, close}: AboutPopupProps): JSX.Element { const styles = React.useContext(StylesContext); return ( - + title="About" + defaultButtonIndex={0}> Version: {VersionInfo.getConstants().appVersion} Source code: @@ -30,7 +31,7 @@ function AboutPopup({show, close}: AboutPopupProps): JSX.Element { text='GitHub' url='https://github.com/chrisglein/artificial-chat/'/> - + ); } diff --git a/src/AiResponse.tsx b/src/AiResponse.tsx index ba05409..0fcd96c 100644 --- a/src/AiResponse.tsx +++ b/src/AiResponse.tsx @@ -22,7 +22,7 @@ import { import { StylesContext } from './Styles'; import { FeedbackContext } from './Feedback'; import Clipboard from '@react-native-clipboard/clipboard'; -import Markdown from 'react-native-markdown-display'; +import Markdown from 'react-native-markdown-display-updated'; type AiImageResponseProps = { imageUrls?: string[]; diff --git a/src/Feedback.tsx b/src/Feedback.tsx index eeb5fdb..cb1f0f9 100644 --- a/src/Feedback.tsx +++ b/src/Feedback.tsx @@ -7,7 +7,7 @@ import { TextInput, View, } from 'react-native'; -import {DialogFrame} from './Popups'; +import { ContentDialog } from './Popups'; import { StylesContext } from './Styles'; import VersionInfo from './NativeVersionInfo' @@ -29,27 +29,31 @@ function FeedbackPopup({show, close, isPositive, response}: FeedbackPopupProps): const [thisIsNotHelpful, setThisIsNotHelpful] = React.useState(false); const buttons = [ - ]; - const buttonList = populatedButtons.map((button, index) => {button}); - - return ( - close()} - style={{height: '100%'}}> - - - - {title} - - - {children} - - - - - {buttonList} - - - - - ) -} - type DialogSectionProps = PropsWithChildren<{ header: string, }>; @@ -81,4 +35,4 @@ function DialogSection({children, header}: DialogSectionProps): JSX.Element { ); } -export { PopupsContext, DialogFrame, DialogSection } \ No newline at end of file +export { PopupsContext, ContentDialog, DialogSection } \ No newline at end of file diff --git a/src/Settings.tsx b/src/Settings.tsx index bb3e1e9..b29d73d 100644 --- a/src/Settings.tsx +++ b/src/Settings.tsx @@ -5,7 +5,7 @@ import { View, } from 'react-native'; import { - DialogFrame, + ContentDialog, DialogSection, } from './Popups'; import {StylesContext} from './Styles'; @@ -160,24 +160,27 @@ function SettingsPopup({show, close}: SettingsPopupProps): JSX.Element { } const buttons = [ - , - - ]; + } + } + ]; return ( - + buttons={buttons} + defaultButtonIndex={0}> AI Endpoint @@ -248,7 +251,7 @@ function SettingsPopup({show, close}: SettingsPopupProps): JSX.Element { value={delayForArtificialResponse.toString()}/> - + ); } diff --git a/windows/artificialChat/artificialChat.vcxproj b/windows/artificialChat/artificialChat.vcxproj index ca203b4..42e7068 100644 --- a/windows/artificialChat/artificialChat.vcxproj +++ b/windows/artificialChat/artificialChat.vcxproj @@ -80,8 +80,7 @@ Always x86|x64 0 - 910162D19999963017448FD45AA25C7B5FC5467F - True + False SHA256 @@ -201,8 +200,6 @@ - - false diff --git a/windows/artificialChat/artificialChat.vcxproj.filters b/windows/artificialChat/artificialChat.vcxproj.filters index 851ba8c..54091d7 100644 --- a/windows/artificialChat/artificialChat.vcxproj.filters +++ b/windows/artificialChat/artificialChat.vcxproj.filters @@ -172,7 +172,6 @@ - diff --git a/windows/artificialChat/artificialChat_TemporaryKey.pfx b/windows/artificialChat/artificialChat_TemporaryKey.pfx deleted file mode 100644 index 5dfddd0..0000000 Binary files a/windows/artificialChat/artificialChat_TemporaryKey.pfx and /dev/null differ diff --git a/windows/artificialChat/packages.config b/windows/artificialChat/packages.config index 4dda557..16b6c0a 100644 --- a/windows/artificialChat/packages.config +++ b/windows/artificialChat/packages.config @@ -1,5 +1,6 @@ - + + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 90f0a48..384baa9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1967,10 +1967,10 @@ dependencies: merge-options "^3.0.4" -"@react-native-clipboard/clipboard@^1.11.2": - version "1.11.2" - resolved "https://registry.yarnpkg.com/@react-native-clipboard/clipboard/-/clipboard-1.11.2.tgz#e826d0336b34e67294aaffa6878308900bc7d197" - integrity sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ== +"@react-native-clipboard/clipboard@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@react-native-clipboard/clipboard/-/clipboard-1.12.1.tgz#a23f9defb732077afa860d0598baa95f5ee9f54b" + integrity sha512-+PNk8kflpGte0W1Nz61/Dp8gHTxyuRjkVyRYBawymSIGTDHCC/zOJSbig6kGIkD8MeaGHC2vGYQJyUyCrgVPBQ== "@react-native-community/cli-clean@^10.0.0": version "10.1.1" @@ -2179,10 +2179,10 @@ resolved "https://registry.yarnpkg.com/@react-native-community/eslint-plugin/-/eslint-plugin-1.3.0.tgz#9e558170c106bbafaa1ef502bd8e6d4651012bf9" integrity sha512-+zDZ20NUnSWghj7Ku5aFphMzuM9JulqCW+aPXT6IfIXFbb8tzYTTOSeRFOtuekJ99ibW2fUCSsjuKNlwDIbHFg== -"@react-native-picker/picker@^2.2.1": - version "2.4.8" - resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.4.8.tgz#a1a21f3d6ecadedbc3f0b691a444ddd7baa081f8" - integrity sha512-5NQ5XPo1B03YNqKFrV6h9L3CQaHlB80wd4ETHUEABRP2iLh7FHLVObX2GfziD+K/VJb8G4KZcZ23NFBFP1f7bg== +"@react-native-picker/picker@^2.5.1": + version "2.5.1" + resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.5.1.tgz#dfa13d5b97bfbedf1f7e7c608181a82f1d58b351" + integrity sha512-/sADUfQsosMRYtrqqL3ZYZSECRygj0fXtpRLqxJfwuMEoqfvfn40756R6B1alzusVvDRZFI0ari0iQid56hA/Q== "@react-native-windows/cli@0.71.1": version "0.71.1" @@ -7239,6 +7239,11 @@ react-native-codegen@^0.71.3: jscodeshift "^0.13.1" nullthrows "^1.1.1" +react-native-content-dialog@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/react-native-content-dialog/-/react-native-content-dialog-0.2.0.tgz#715fc0404fe6b05ad8efad41b6ad5f4eee9bad22" + integrity sha512-TB+UUtjNzYOiJ2YyC6j+dN1dYR6kx+E8zHQSm/gNhsaUbUpV0XMDQIaoiV2kUnkGpOPFg4Y9Jx4iPt5vQPIehQ== + react-native-fit-image@^1.5.5: version "1.5.5" resolved "https://registry.yarnpkg.com/react-native-fit-image/-/react-native-fit-image-1.5.5.tgz#c660d1ad74b9dcaa1cba27a0d9c23837e000226c" @@ -7251,10 +7256,10 @@ react-native-gradle-plugin@^0.71.12: resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.14.tgz#cc399662f04fbfcc0e352d03eae1d3efbd5f635a" integrity sha512-nnLawTZEPPRAKq92UqDkzoGgCBl9aa9zAihFHMwmwzn4WRVdK4O6Cd4XYiyoNOiQzx3Hh9k5WOckHE80C92ivQ== -react-native-markdown-display@^7.0.0-alpha.2: - version "7.0.0-alpha.2" - resolved "https://registry.yarnpkg.com/react-native-markdown-display/-/react-native-markdown-display-7.0.0-alpha.2.tgz#a48a70d3cb5c510a52ecf7f1509a4a3d14d728aa" - integrity sha512-Od1a4wJEcVGwO1bh02sHivsEkKKpu99+ew/OtmVTPRmfT8V3B0aTut7k7ICV0Vej9F4ZjylRHvm28/maYUBeGw== +react-native-markdown-display-updated@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/react-native-markdown-display-updated/-/react-native-markdown-display-updated-7.0.0.tgz#c5c9dc25670573700843540f86c74e972cd74508" + integrity sha512-0bLyxigFEP0M1vzvxMILyCltyQGvdYgriuOLzLBFot9YNJPbaIYtR2c9o432gzPLotGpkU+HytgSD/cea6JygQ== dependencies: css-to-react-native "^3.0.0" markdown-it "^10.0.0"