~haowenl/vorg-windows

764df769e8f6611c16ef6c21ac117cb8aa56f372 — Haowen Liu 1 year, 8 months ago 4106009
Implement file import
M .gitignore => .gitignore +4 -1
@@ 1,3 1,6 @@
/.vs/
/packages/
/x64/
\ No newline at end of file
/x64/
/AppPackages/
/Debug/
/Release/
\ No newline at end of file

M .gitmodules => .gitmodules +1 -0
@@ 1,3 1,4 @@
[submodule "libvorg"]
	path = libvorg
	url = https://git.sr.ht/~haowenl/libvorg
	branch = main

M libvorg => libvorg +1 -1
@@ 1,1 1,1 @@
Subproject commit 9ed7faa4aaf511a0735099833db036b4b69fa286
Subproject commit 5e3a83f27cc1765e19ab38f453ca4335a5f6a5fb

M vorg-windows.sln => vorg-windows.sln +1 -1
@@ 5,7 5,7 @@ VisualStudioVersion = 17.5.33414.496
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vorg-windows", "vorg-windows\vorg-windows.vcxproj", "{F873567E-C027-48F4-ADCA-B5A7C3CE8ACC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvorg", "..\..\..\sr.ht\libvorg\build\libvorg\libvorg.vcxproj", "{1B58466A-057A-32B3-9522-A6C017EE90AA}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libvorg", "libvorg\build\libvorg\libvorg.vcxproj", "{1B58466A-057A-32B3-9522-A6C017EE90AA}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution

M vorg-windows/.gitignore => vorg-windows/.gitignore +3 -1
@@ 1,2 1,4 @@
/x64/
/Generated Files/
\ No newline at end of file
/Generated Files/
/Debug/
/Release/
\ No newline at end of file

M vorg-windows/App.xaml.cpp => vorg-windows/App.xaml.cpp +42 -0
@@ 56,6 56,36 @@ bool App::OpenRepo(const winrt::hstring &path)
    return mRepo->initRepo();
}

bool App::SetImportFile(const winrt::hstring &path)
{
    std::string pathUTF8 = winrt::to_string(path);
    return mRepo->prepareFileImport(pathUTF8) == Vorg::VorgRepo::Success;
}

bool App::SetImportFolder(const winrt::hstring &path)
{
    std::string pathUTF8 = winrt::to_string(path);
    return mRepo->prepareFolderImport(pathUTF8) == Vorg::VorgRepo::Success;
}

winrt::hstring App::GetNextFile() const
{
    std::string fileUTF8 = mRepo->getNextFilePath().string();
    return winrt::to_hstring(fileUTF8);
}

bool App::ImportNext(const winrt::hstring &title, const winrt::hstring &studio,
                     const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &actors,
                     const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &tags)
{
    std::string titleUTF8 = winrt::to_string(title);
    std::string studioUTF8 = winrt::to_string(studio);
    std::vector<std::string> actorsStd = WinrtToStdVector(actors);
    std::vector<std::string> tagsStd = WinrtToStdVector(tags);

    return mRepo->importNext(titleUTF8, studioUTF8, actorsStd, tagsStd) == Vorg::VorgRepo::Success;
}

winrt::hstring App::GetVorgError() const
{
    if (mRepo == nullptr)


@@ 65,4 95,16 @@ winrt::hstring App::GetVorgError() const
    std::string errorUTF8 = mRepo->getErrorMsg();
    return winrt::to_hstring(errorUTF8);
}
std::vector<std::string> App::WinrtToStdVector(
    const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &input)
{
    int n = input.Size();
    std::vector<std::string> result;
    for (int i = 0; i < n; ++i)
    {
        std::string elemUTF8 = winrt::to_string(input.GetAt(i));
        result.emplace_back(std::move(elemUTF8));
    }
    return result;
}
} // namespace winrt::vorg_windows::implementation

M vorg-windows/App.xaml.h => vorg-windows/App.xaml.h +9 -1
@@ 17,15 17,23 @@ struct App : AppT<App>

    // App logics
    bool OpenRepo(const winrt::hstring &path);
    bool SetImportFile(const winrt::hstring &path);
    bool SetImportFolder(const winrt::hstring &path);
    winrt::hstring GetNextFile() const;
    bool ImportNext(const winrt::hstring &title, const winrt::hstring &studio,
                    const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &actors,
                    const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &tags);

    // Error handling
    winrt::hstring GetVorgError() const;
    void ShowVorgError() const;

    // Members
    winrt::Microsoft::UI::Xaml::Window mWindow{nullptr};

  private:
    std::unique_ptr<Vorg::VorgRepo> mRepo;

    static std::vector<std::string> WinrtToStdVector(
        const winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &input);
};
} // namespace winrt::vorg_windows::implementation

A vorg-windows/ImportEditPage.idl => vorg-windows/ImportEditPage.idl +24 -0
@@ 0,0 1,24 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

namespace vorg_windows
{
    [default_interface]
    runtimeclass ImportEditPage : Microsoft.UI.Xaml.Controls.Page
    {
        ImportEditPage();
        Windows.Foundation.Collections.IObservableVector<String> Actors
        {
            get;
        };
        Windows.Foundation.Collections.IObservableVector<String> Tags
        {
            get;
        };
        Windows.Media.Core.MediaSource MediaSource
        {
            get;
            set;
        };
    }
}

A vorg-windows/ImportEditPage.xaml => vorg-windows/ImportEditPage.xaml +213 -0
@@ 0,0 1,213 @@
<!--  Copyright (c) Microsoft Corporation and Contributors.  -->
<!--  Licensed under the MIT License.  -->

<Page
    x:Class="vorg_windows.ImportEditPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:vorg_windows"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Vertical">
        <MediaPlayerElement
            x:Name="MediaPlayer"
            AreTransportControlsEnabled="True"
            BorderThickness="0"
            CornerRadius="16"
            Source="{x:Bind MediaSource}" />

        <Grid
            Margin="0,16,0,0"
            ColumnSpacing="16"
            RowSpacing="8">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>

            <!--  Title  -->
            <TextBlock Grid.Row="0" Grid.Column="0">Title</TextBlock>
            <TextBox
                x:Name="TitleInput"
                Grid.Row="1"
                Grid.Column="0" />

            <!--  Studio  -->
            <TextBlock Grid.Row="0" Grid.Column="1">Studio</TextBlock>
            <AutoSuggestBox
                x:Name="StudioInput"
                Grid.Row="1"
                Grid.Column="1" />
        </Grid>

        <Grid
            Margin="0,16,0,0"
            ColumnSpacing="16"
            RowSpacing="8">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>

            <!--  Actors  -->
            <TextBlock Grid.Row="0" Grid.Column="0">Actors</TextBlock>
            <Grid
                Grid.Row="1"
                Grid.Column="0"
                ColumnSpacing="8">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <AutoSuggestBox
                    x:Name="ActorNameInput"
                    Grid.Column="0"
                    HorizontalAlignment="Stretch"
                    KeyUp="ActorNameInput_KeyUp" />
                <Button
                    x:Name="ActorsSubmitButton"
                    Grid.Column="1"
                    VerticalAlignment="Stretch"
                    Click="ActorsSubmitButton_Click"
                    Content="&#xE710;"
                    FontFamily="Segoe MDL2 Assets"
                    IsTabStop="False" />
            </Grid>
            <ListView
                Grid.Row="2"
                Grid.Column="0"
                ItemsSource="{x:Bind Actors}"
                SelectionMode="Single">
                <ItemsControl.ItemTemplate>
                    <DataTemplate x:DataType="x:String">
                        <UserControl PointerEntered="UserControl_PointerEntered" PointerExited="UserControl_PointerExited">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <TextBlock
                                    Grid.Column="0"
                                    VerticalAlignment="Center"
                                    Text="{x:Bind}" />
                                <Button
                                    x:Name="ActorsDeleteButton"
                                    Grid.Column="1"
                                    Click="ActorsDeleteButton_Click"
                                    Content="&#xE711;"
                                    FontFamily="Segoe MDL2 Assets"
                                    Visibility="Collapsed" />
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="HoverButtonsHidden" />
                                        <VisualState x:Name="HoverButtonsShown">
                                            <VisualState.Setters>
                                                <Setter Target="ActorsDeleteButton.Visibility" Value="Visible" />
                                            </VisualState.Setters>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                            </Grid>
                        </UserControl>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemContainerStyle>
                    <Style BasedOn="{StaticResource DefaultListViewItemStyle}" TargetType="ListViewItem">
                        <Setter Property="IsTabStop" Value="False" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ListView>

            <!--  Tags  -->
            <TextBlock Grid.Row="0" Grid.Column="1">Tags</TextBlock>
            <Grid
                Grid.Row="1"
                Grid.Column="1"
                ColumnSpacing="8">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <AutoSuggestBox
                    x:Name="TagNameInput"
                    Grid.Column="0"
                    HorizontalAlignment="Stretch"
                    KeyUp="TagNameInput_KeyUp" />
                <Button
                    x:Name="TagsSubmitButton"
                    Grid.Column="1"
                    VerticalAlignment="Stretch"
                    Click="TagsSubmitButton_Click"
                    Content="&#xE710;"
                    FontFamily="Segoe MDL2 Assets"
                    IsTabStop="False" />
            </Grid>
            <ListView
                Grid.Row="2"
                Grid.Column="1"
                ItemsSource="{x:Bind Tags}"
                SelectionMode="Single">
                <ItemsControl.ItemTemplate>
                    <DataTemplate x:DataType="x:String">
                        <UserControl PointerEntered="UserControl_PointerEntered" PointerExited="UserControl_PointerExited">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <TextBlock
                                    Grid.Column="0"
                                    VerticalAlignment="Center"
                                    Text="{x:Bind}" />
                                <Button
                                    x:Name="TagsDeleteButton"
                                    Grid.Column="1"
                                    Click="TagsDeleteButton_Click"
                                    Content="&#xE711;"
                                    FontFamily="Segoe MDL2 Assets"
                                    Visibility="Collapsed" />
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="HoverButtonsHidden" />
                                        <VisualState x:Name="HoverButtonsShown">
                                            <VisualState.Setters>
                                                <Setter Target="TagsDeleteButton.Visibility" Value="Visible" />
                                            </VisualState.Setters>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                            </Grid>
                        </UserControl>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemContainerStyle>
                    <Style BasedOn="{StaticResource DefaultListViewItemStyle}" TargetType="ListViewItem">
                        <Setter Property="IsTabStop" Value="False" />
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ListView>
        </Grid>

        <Button
            Margin="0,16,0,0"
            HorizontalAlignment="Right"
            Click="SubmitButton_Click"
            Style="{StaticResource AccentButtonStyle}">
            <StackPanel Orientation="Horizontal" Spacing="8">
                <TextBlock>Import</TextBlock>
                <SymbolIcon Symbol="Import" />
            </StackPanel>
        </Button>
    </StackPanel>
</Page>

A vorg-windows/ImportEditPage.xaml.cpp => vorg-windows/ImportEditPage.xaml.cpp +178 -0
@@ 0,0 1,178 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#include "pch.h"

#include "ImportEditPage.xaml.h"
#if __has_include("ImportEditPage.g.cpp")
#include "ImportEditPage.g.cpp"
#endif

using namespace winrt;
using namespace Microsoft::UI::Xaml;

namespace winrt::vorg_windows::implementation
{
ImportEditPage::ImportEditPage()
    : mActors(winrt::single_threaded_observable_vector<winrt::hstring>()),
      mTags(winrt::single_threaded_observable_vector<winrt::hstring>())
{
    InitializeComponent();

    // Initialize app ptr
    mApp.copy_from(winrt::get_self<vorg_windows::implementation::App>(
        Application::Current().as<winrt::default_interface<vorg_windows::implementation::App>>()));
}

winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> ImportEditPage::Actors() const
{
    return mActors;
}

winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> ImportEditPage::Tags() const
{
    return mTags;
}

winrt::Windows::Media::Core::MediaSource ImportEditPage::MediaSource() const
{
    return mMediaSource;
}

void ImportEditPage::MediaSource(const winrt::Windows::Media::Core::MediaSource &mediaSource)
{
    mMediaSource = mediaSource;
}

void ImportEditPage::UserControl_PointerEntered(const winrt::Windows::Foundation::IInspectable &sender,
                                                const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &)
{
    winrt::Microsoft::UI::Xaml::Controls::UserControl userControl =
        sender.as<winrt::Microsoft::UI::Xaml::Controls::UserControl>();
    VisualStateManager::GoToState(userControl, L"HoverButtonsShown", false);
}

void ImportEditPage::UserControl_PointerExited(const winrt::Windows::Foundation::IInspectable &sender,
                                               const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &)
{
    winrt::Microsoft::UI::Xaml::Controls::UserControl userControl =
        sender.as<winrt::Microsoft::UI::Xaml::Controls::UserControl>();
    VisualStateManager::GoToState(userControl, L"HoverButtonsHidden", false);
}

void ImportEditPage::ActorsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,
                                              const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    winrt::Microsoft::UI::Xaml::Controls::Button button = sender.as<winrt::Microsoft::UI::Xaml::Controls::Button>();
    winrt::Windows::Foundation::IInspectable dataContext = button.DataContext();
    winrt::hstring itemName = dataContext.as<winrt::hstring>();
    DelteFromVector(mActors, itemName);
}

void ImportEditPage::TagsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,
                                            const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    winrt::Microsoft::UI::Xaml::Controls::Button button = sender.as<winrt::Microsoft::UI::Xaml::Controls::Button>();
    winrt::Windows::Foundation::IInspectable dataContext = button.DataContext();
    winrt::hstring itemName = dataContext.as<winrt::hstring>();
    DelteFromVector(mTags, itemName);
}

void ImportEditPage::ActorsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                              const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    AddToActors(ActorNameInput().Text());
}

void ImportEditPage::TagsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                            const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    AddToTags(TagNameInput().Text());
}

void ImportEditPage::ActorNameInput_KeyUp(winrt::Windows::Foundation::IInspectable const &,
                                          winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const &e)
{
    if (e.Key() == winrt::Windows::System::VirtualKey::Enter)
    {
        AddToActors(ActorNameInput().Text());
    }
}

void ImportEditPage::TagNameInput_KeyUp(winrt::Windows::Foundation::IInspectable const &,
                                        winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const &e)
{
    if (e.Key() == winrt::Windows::System::VirtualKey::Enter)
    {
        AddToTags(TagNameInput().Text());
    }
}

void ImportEditPage::SubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                        const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    mApp->ImportNext(TitleInput().Text(), StudioInput().Text(), mActors, mTags);
}

void ImportEditPage::DelteFromVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                                     const winrt::hstring &item)
{
    for (uint32_t i = 0; i < vector.Size(); ++i)
    {
        if (vector.GetAt(i) == item)
        {
            vector.RemoveAt(i);
            return;
        }
    }
}

bool ImportEditPage::FindInVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                                  const winrt::hstring &item)
{
    for (uint32_t i = 0; i < vector.Size(); ++i)
    {
        if (vector.GetAt(i) == item)
        {
            return true;
        }
    }
    return false;
}

void ImportEditPage::TrimStringView(std::wstring_view &view)
{
    while (!view.empty() && isspace(view.front()))
    {
        view.remove_prefix(1);
    }
    while (!view.empty() && isspace(view.back()))
    {
        view.remove_suffix(1);
    }
}

void ImportEditPage::AddToActors(const winrt::hstring &actor)
{
    std::wstring_view nameView = actor;
    TrimStringView(nameView);
    winrt::hstring trimmedName{nameView};
    if (!trimmedName.empty() && !FindInVector(mActors, trimmedName))
    {
        mActors.Append(trimmedName);
    }
    ActorNameInput().Text(L"");
}

void ImportEditPage::AddToTags(const winrt::hstring &tag)
{
    std::wstring_view nameView = tag;
    TrimStringView(nameView);
    winrt::hstring trimmedName{nameView};
    if (!nameView.empty() && !FindInVector(mTags, trimmedName))
    {
        mTags.Append(trimmedName);
    }
    TagNameInput().Text(L"");
}
} // namespace winrt::vorg_windows::implementation

A vorg-windows/ImportEditPage.xaml.h => vorg-windows/ImportEditPage.xaml.h +65 -0
@@ 0,0 1,65 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#pragma once

#include "ImportEditPage.g.h"

#include "App.xaml.h"

namespace winrt::vorg_windows::implementation
{
struct ImportEditPage : ImportEditPageT<ImportEditPage>
{
    ImportEditPage();

    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> Actors() const;
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> Tags() const;

    winrt::Windows::Media::Core::MediaSource MediaSource() const;
    void MediaSource(const winrt::Windows::Media::Core::MediaSource &mediaSource);

    void UserControl_PointerEntered(const winrt::Windows::Foundation::IInspectable &sender,
                                    const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &);
    void UserControl_PointerExited(const winrt::Windows::Foundation::IInspectable &sender,
                                   const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &);
    void ActorsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,
                                  const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);
    void TagsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,
                                const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);

    void ActorsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                  const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);
    void TagsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);

    void ActorNameInput_KeyUp(winrt::Windows::Foundation::IInspectable const &,
                                winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const &e);
    void TagNameInput_KeyUp(winrt::Windows::Foundation::IInspectable const &,
                              winrt::Microsoft::UI::Xaml::Input::KeyRoutedEventArgs const &e);

    void SubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                            const winrt::Microsoft::UI::Xaml::RoutedEventArgs &);

  private:
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> mActors;
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> mTags;
    winrt::Windows::Media::Core::MediaSource mMediaSource{nullptr};
    winrt::com_ptr<winrt::vorg_windows::implementation::App> mApp;

    static void DelteFromVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                                const winrt::hstring &item);
    static bool FindInVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                             const winrt::hstring &item);
    static void TrimStringView(std::wstring_view &view);
    void AddToActors(const winrt::hstring &actor);
    void AddToTags(const winrt::hstring &tag);
};
} // namespace winrt::vorg_windows::implementation

namespace winrt::vorg_windows::factory_implementation
{
struct ImportEditPage : ImportEditPageT<ImportEditPage, implementation::ImportEditPage>
{
};
} // namespace winrt::vorg_windows::factory_implementation

M vorg-windows/ImportPage.idl => vorg-windows/ImportPage.idl +0 -8
@@ 6,13 6,5 @@ namespace vorg_windows
[default_interface] runtimeclass ImportPage : Microsoft.UI.Xaml.Controls.Page
{
    ImportPage();
    Windows.Foundation.Collections.IObservableVector<String> Actors
    {
        get;
    };
    Windows.Foundation.Collections.IObservableVector<String> Tags
    {
        get;
    };
}
} // namespace vorg_windows

M vorg-windows/ImportPage.xaml => vorg-windows/ImportPage.xaml +5 -178
@@ 10,11 10,10 @@
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel
    <Grid
        Margin="0,44,0,44"
        HorizontalAlignment="Left"
        VerticalAlignment="Top"
        Orientation="Vertical">
        HorizontalAlignment="Stretch"
        VerticalAlignment="Stretch">
        <Grid
            Height="40"
            Margin="0,0,0,22"


@@ 27,178 26,6 @@
                Text="Import Video" />
        </Grid>

        <MediaPlayerElement AreTransportControlsEnabled="True" Source="https://samplelib.com/lib/preview/mp4/sample-5s.mp4" />

        <Grid
            Margin="0,16,0,0"
            ColumnSpacing="16"
            RowSpacing="8">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>

            <!--  Title  -->
            <TextBlock Grid.Row="0" Grid.Column="0">Title</TextBlock>
            <TextBox Grid.Row="1" Grid.Column="0" />

            <!--  Studio  -->
            <TextBlock Grid.Row="0" Grid.Column="1">Studio</TextBlock>
            <AutoSuggestBox Grid.Row="1" Grid.Column="1" />
        </Grid>

        <Grid
            Margin="0,16,0,0"
            ColumnSpacing="16"
            RowSpacing="8">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>

            <!--  Actors  -->
            <TextBlock Grid.Row="0" Grid.Column="0">Actors</TextBlock>
            <Grid
                Grid.Row="1"
                Grid.Column="0"
                ColumnSpacing="8">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <AutoSuggestBox
                    x:Name="ActorNameInput"
                    Grid.Column="0"
                    HorizontalAlignment="Stretch" />
                <Button
                    x:Name="ActorsSubmitButton"
                    Grid.Column="1"
                    VerticalAlignment="Stretch"
                    Click="ActorsSubmitButton_Click"
                    Content="&#xE710;"
                    FontFamily="Segoe MDL2 Assets" />
            </Grid>
            <ListView
                Grid.Row="2"
                Grid.Column="0"
                ItemsSource="{x:Bind Actors}"
                SelectionMode="Single">
                <ItemsControl.ItemTemplate>
                    <DataTemplate x:DataType="x:String">
                        <UserControl PointerEntered="UserControl_PointerEntered" PointerExited="UserControl_PointerExited">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <TextBlock
                                    Grid.Column="0"
                                    VerticalAlignment="Center"
                                    Text="{x:Bind}" />
                                <Button
                                    x:Name="ActorsDeleteButton"
                                    Grid.Column="1"
                                    Click="ActorsDeleteButton_Click"
                                    Content="&#xE711;"
                                    FontFamily="Segoe MDL2 Assets"
                                    Visibility="Collapsed" />
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="HoverButtonsHidden" />
                                        <VisualState x:Name="HoverButtonsShown">
                                            <VisualState.Setters>
                                                <Setter Target="ActorsDeleteButton.Visibility" Value="Visible" />
                                            </VisualState.Setters>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                            </Grid>
                        </UserControl>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ListView>

            <!--  Tags  -->
            <TextBlock Grid.Row="0" Grid.Column="1">Tags</TextBlock>
            <Grid
                Grid.Row="1"
                Grid.Column="1"
                ColumnSpacing="8">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <AutoSuggestBox
                    x:Name="TagNameInput"
                    Grid.Column="0"
                    HorizontalAlignment="Stretch" />
                <Button
                    x:Name="TagsSubmitButton"
                    Grid.Column="1"
                    VerticalAlignment="Stretch"
                    Click="TagsSubmitButton_Click"
                    Content="&#xE710;"
                    FontFamily="Segoe MDL2 Assets" />
            </Grid>
            <ListView
                Grid.Row="2"
                Grid.Column="1"
                ItemsSource="{x:Bind Tags}"
                SelectionMode="Single">
                <ItemsControl.ItemTemplate>
                    <DataTemplate x:DataType="x:String">
                        <UserControl PointerEntered="UserControl_PointerEntered" PointerExited="UserControl_PointerExited">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <TextBlock
                                    Grid.Column="0"
                                    VerticalAlignment="Center"
                                    Text="{x:Bind}" />
                                <Button
                                    x:Name="TagsDeleteButton"
                                    Grid.Column="1"
                                    Click="TagsDeleteButton_Click"
                                    Content="&#xE711;"
                                    FontFamily="Segoe MDL2 Assets"
                                    Visibility="Collapsed" />
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="HoverButtonsHidden" />
                                        <VisualState x:Name="HoverButtonsShown">
                                            <VisualState.Setters>
                                                <Setter Target="TagsDeleteButton.Visibility" Value="Visible" />
                                            </VisualState.Setters>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                            </Grid>
                        </UserControl>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ListView>
        </Grid>

        <Button
            Margin="0,16,0,0"
            HorizontalAlignment="Right"
            Click="SubmitButton_Click"
            Style="{StaticResource AccentButtonStyle}">
            <StackPanel Orientation="Horizontal" Spacing="8">
                <TextBlock>Import</TextBlock>
                <SymbolIcon Symbol="Import" />
            </StackPanel>
        </Button>
    </StackPanel>
        <Frame x:Name="ContentFrame" />
    </Grid>
</Page>

M vorg-windows/ImportPage.xaml.cpp => vorg-windows/ImportPage.xaml.cpp +24 -90
@@ 8,6 8,8 @@
#include "ImportPage.g.cpp"
#endif

#include "ImportSelectionPage.xaml.h"

using namespace winrt;
using namespace Microsoft::UI::Xaml;



@@ 17,105 19,37 @@ using namespace Microsoft::UI::Xaml;
namespace winrt::vorg_windows::implementation
{
ImportPage::ImportPage()
    : mActors(winrt::single_threaded_observable_vector<winrt::hstring>()),
      mTags(winrt::single_threaded_observable_vector<winrt::hstring>())
{
    InitializeComponent();
    mActors.Append(L"ABC");
    mActors.Append(L"DEF");
    mTags.Append(L"ABC");
}

winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> ImportPage::Actors()
{
    return mActors;
}

winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> ImportPage::Tags()
{
    return mTags;
}

void ImportPage::UserControl_PointerEntered(const winrt::Windows::Foundation::IInspectable &sender,
                                            const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &)
{
    winrt::Microsoft::UI::Xaml::Controls::UserControl userControl =
        sender.as<winrt::Microsoft::UI::Xaml::Controls::UserControl>();
    VisualStateManager::GoToState(userControl, L"HoverButtonsShown", false);
}

void ImportPage::UserControl_PointerExited(const winrt::Windows::Foundation::IInspectable &sender,
                                           const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &)
{
    winrt::Microsoft::UI::Xaml::Controls::UserControl userControl =
        sender.as<winrt::Microsoft::UI::Xaml::Controls::UserControl>();
    VisualStateManager::GoToState(userControl, L"HoverButtonsHidden", false);
}

void ImportPage::ActorsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,
                                          const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    winrt::Microsoft::UI::Xaml::Controls::Button button = sender.as<winrt::Microsoft::UI::Xaml::Controls::Button>();
    winrt::Windows::Foundation::IInspectable dataContext = button.DataContext();
    winrt::hstring itemName = dataContext.as<winrt::hstring>();
    DelteFromVector(mActors, itemName);
}
    // Initialize app ptr
    mApp.copy_from(winrt::get_self<vorg_windows::implementation::App>(
        Application::Current().as<winrt::default_interface<vorg_windows::implementation::App>>()));

void ImportPage::TagsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,
                                        const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    winrt::Microsoft::UI::Xaml::Controls::Button button = sender.as<winrt::Microsoft::UI::Xaml::Controls::Button>();
    winrt::Windows::Foundation::IInspectable dataContext = button.DataContext();
    winrt::hstring itemName = dataContext.as<winrt::hstring>();
    DelteFromVector(mTags, itemName);
}
    // Starts in ImportSelectionPage
    ContentFrame().Navigate(winrt::xaml_typename<winrt::vorg_windows::ImportSelectionPage>());

void ImportPage::ActorsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                          const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
    winrt::hstring actorName = ActorNameInput().Text();
    if (!FindInVector(mActors, actorName))
        mActors.Append(actorName);
    ActorNameInput().Text(L"");
    // Register SelectionFinished handler
    vorg_windows::ImportSelectionPage selectionPage = ContentFrame().Content().as<vorg_windows::ImportSelectionPage>();
    mSelectionFinishedToken = selectionPage.SelectionFinished(
        [this](auto &sender, auto &args) { this->ImportSelectionPage_SelectionFinished(sender, args); });
}

void ImportPage::TagsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                        const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
void ImportPage::ImportSelectionPage_SelectionFinished(const vorg_windows::ImportSelectionPage &,
                                                       const winrt::Windows::Foundation::IInspectable &)
{
    winrt::hstring tagName = TagNameInput().Text();
    if (!FindInVector(mTags, tagName))
        mTags.Append(tagName);
    TagNameInput().Text(L"");
}
    // Remove SelectionFinished handler
    vorg_windows::ImportSelectionPage selectionPage = ContentFrame().Content().as<vorg_windows::ImportSelectionPage>();
    selectionPage.SelectionFinished(mSelectionFinishedToken);

void ImportPage::SubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                    const winrt::Microsoft::UI::Xaml::RoutedEventArgs &)
{
}

void ImportPage::DelteFromVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                                 const winrt::hstring &item)
{
    for (uint32_t i = 0; i < vector.Size(); ++i)
    {
        if (vector.GetAt(i) == item)
        {
            vector.RemoveAt(i);
            return;
        }
    }
}
    // Navigate to ImportEditPage
    ContentFrame().Navigate(winrt::xaml_typename<winrt::vorg_windows::ImportEditPage>());

bool ImportPage::FindInVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                              const winrt::hstring &item)
{
    for (uint32_t i = 0; i < vector.Size(); ++i)
    {
        if (vector.GetAt(i) == item)
        {
            return true;
        }
    }
    return false;
    // Set ImportEditPage MediaSource
    vorg_windows::ImportEditPage editPage = ContentFrame().Content().as<vorg_windows::ImportEditPage>();
    winrt::hstring filePath = mApp->GetNextFile();
    winrt::Windows::Media::Core::MediaSource mediaSouce =
        winrt::Windows::Media::Core::MediaSource::CreateFromUri(winrt::Windows::Foundation::Uri{filePath});
    editPage.MediaSource(mediaSouce);
}
} // namespace winrt::vorg_windows::implementation

M vorg-windows/ImportPage.xaml.h => vorg-windows/ImportPage.xaml.h +6 -25
@@ 5,40 5,21 @@

#include "ImportPage.g.h"

#include "App.xaml.h"

namespace winrt::vorg_windows::implementation
{
struct ImportPage : ImportPageT<ImportPage>
{
    ImportPage();

    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> Actors();
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> Tags();

    void UserControl_PointerEntered(const winrt::Windows::Foundation::IInspectable &sender,
                                    const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &);
    void UserControl_PointerExited(const winrt::Windows::Foundation::IInspectable &sender,
                                   const winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs &);
    void ActorsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,
                                  const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);
    void TagsDeleteButton_Click(const winrt::Windows::Foundation::IInspectable &sender,
                                const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);

    void ActorsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                  const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);
    void TagsSubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                                const winrt::Microsoft::UI::Xaml::RoutedEventArgs &e);

    void SubmitButton_Click(const winrt::Windows::Foundation::IInspectable &,
                            const winrt::Microsoft::UI::Xaml::RoutedEventArgs &);
    void ImportSelectionPage_SelectionFinished(const vorg_windows::ImportSelectionPage &,
                                               const winrt::Windows::Foundation::IInspectable &);

  private:
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> mActors;
    winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> mTags;
    winrt::event_token mSelectionFinishedToken;

    void DelteFromVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                         const winrt::hstring &item);
    bool FindInVector(winrt::Windows::Foundation::Collections::IObservableVector<winrt::hstring> &vector,
                         const winrt::hstring &item);
    winrt::com_ptr<winrt::vorg_windows::implementation::App> mApp{nullptr};
};
} // namespace winrt::vorg_windows::implementation


A vorg-windows/ImportSelectionPage.idl => vorg-windows/ImportSelectionPage.idl +12 -0
@@ 0,0 1,12 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

namespace vorg_windows
{
[default_interface] runtimeclass ImportSelectionPage : Microsoft.UI.Xaml.Controls.Page
{
    ImportSelectionPage();

    event Windows.Foundation.TypedEventHandler<ImportSelectionPage, Object> SelectionFinished;
}
} // namespace vorg_windows

A vorg-windows/ImportSelectionPage.xaml => vorg-windows/ImportSelectionPage.xaml +43 -0
@@ 0,0 1,43 @@
<!--  Copyright (c) Microsoft Corporation and Contributors.  -->
<!--  Licensed under the MIT License.  -->

<Page
    x:Class="vorg_windows.ImportSelectionPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:vorg_windows"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        Orientation="Horizontal"
        Spacing="32">
        <Button
            x:Name="ImportFileButton"
            Width="128"
            Click="ImportFileButton_Click">
            <StackPanel Padding="0,8,0,2" Spacing="4">
                <FontIcon
                    FontFamily="Segoe MDL2 Assets"
                    FontSize="32"
                    Glyph="&#xE8E5;" />
                <TextBlock>Import File</TextBlock>
            </StackPanel>
        </Button>
        <Button
            x:Name="ImportFolderButton"
            Width="128"
            Click="ImportFolderButton_Click">
            <StackPanel Padding="0,8,0,2" Spacing="4">
                <FontIcon
                    FontFamily="Segoe MDL2 Assets"
                    FontSize="32"
                    Glyph="&#xED43;" />
                <TextBlock>Import Folder</TextBlock>
            </StackPanel>
        </Button>
    </StackPanel>
</Page>

A vorg-windows/ImportSelectionPage.xaml.cpp => vorg-windows/ImportSelectionPage.xaml.cpp +115 -0
@@ 0,0 1,115 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#include "pch.h"

#include "ImportSelectionPage.xaml.h"
#if __has_include("ImportSelectionPage.g.cpp")
#include "ImportSelectionPage.g.cpp"
#endif

using namespace winrt;
using namespace Microsoft::UI::Xaml;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace winrt::vorg_windows::implementation
{
ImportSelectionPage::ImportSelectionPage()
{
    InitializeComponent();
    mApp.copy_from(winrt::get_self<vorg_windows::implementation::App>(
        Application::Current().as<winrt::default_interface<vorg_windows::implementation::App>>()));
}

winrt::fire_and_forget ImportSelectionPage::ImportFileButton_Click(
    winrt::Windows::Foundation::IInspectable const &sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const &e)
{
    // If mHwnd is unitialized, initialize it
    if (mHwnd == nullptr)
    {
        initWndHandle();
    }

    // Launch file chooser
    winrt::Windows::Storage::Pickers::FileOpenPicker filePicker;
    filePicker.SuggestedStartLocation(winrt::Windows::Storage::Pickers::PickerLocationId::VideosLibrary);
    filePicker.as<IInitializeWithWindow>()->Initialize(mHwnd);
    filePicker.FileTypeFilter().ReplaceAll({L".mp4"});
    winrt::Windows::Storage::StorageFile file = co_await filePicker.PickSingleFileAsync();

    if (file != nullptr)
    {
        // Perform requested action
        if (!mApp->SetImportFile(file.Path()))
        {
            // Show dialog with error
            winrt::vorg_windows::ErrorContentDialog dialog;
            dialog.Title(winrt::box_value(L"Error importing folder"));
            dialog.Content(winrt::box_value(mApp->GetVorgError()));
            dialog.XamlRoot(XamlRoot());
            co_await dialog.ShowAsync();
        }
        else
        {
            // Fire open repo event
            mSelectionFinishedEvent(*this, nullptr);
        }
    }
}

winrt::fire_and_forget ImportSelectionPage::ImportFolderButton_Click(
    winrt::Windows::Foundation::IInspectable const &sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const &e)
{
    // If mHwnd is unitialized, initialize it
    if (mHwnd == nullptr)
    {
        initWndHandle();
    }

    // Launch file chooser
    winrt::Windows::Storage::Pickers::FolderPicker folderPicker;
    folderPicker.SuggestedStartLocation(winrt::Windows::Storage::Pickers::PickerLocationId::VideosLibrary);
    folderPicker.as<IInitializeWithWindow>()->Initialize(mHwnd);
    winrt::Windows::Storage::StorageFolder folder = co_await folderPicker.PickSingleFolderAsync();

    if (folder != nullptr)
    {
        // Perform requested action
        if (!mApp->SetImportFolder(folder.Path()))
        {
            // Show dialog with error
            winrt::vorg_windows::ErrorContentDialog dialog;
            dialog.Title(winrt::box_value(L"Error importing folder"));
            dialog.Content(winrt::box_value(mApp->GetVorgError()));
            dialog.XamlRoot(XamlRoot());
            co_await dialog.ShowAsync();
        }
        else
        {
            // Fire open repo event
            mSelectionFinishedEvent(*this, nullptr);
        }
    }
}

winrt::event_token ImportSelectionPage::SelectionFinished(
    const winrt::Windows::Foundation::TypedEventHandler<vorg_windows::ImportSelectionPage,
                                                        winrt::Windows::Foundation::IInspectable> &handler)
{
    return mSelectionFinishedEvent.add(handler);
}

void ImportSelectionPage::SelectionFinished(const winrt::event_token &token)
{
    mSelectionFinishedEvent.remove(token);
}

void ImportSelectionPage::initWndHandle()
{
    auto nativeWindow = mApp->mWindow.try_as<IWindowNative>();
    winrt::check_bool(nativeWindow);
    nativeWindow->get_WindowHandle(&mHwnd);
}
} // namespace winrt::vorg_windows::implementation

A vorg-windows/ImportSelectionPage.xaml.h => vorg-windows/ImportSelectionPage.xaml.h +43 -0
@@ 0,0 1,43 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#pragma once

#include "ImportSelectionPage.g.h"

#include "App.xaml.h"

namespace winrt::vorg_windows::implementation
{
struct ImportSelectionPage : ImportSelectionPageT<ImportSelectionPage>
{
    ImportSelectionPage();

    winrt::fire_and_forget ImportFileButton_Click(winrt::Windows::Foundation::IInspectable const &sender,
                                                  winrt::Microsoft::UI::Xaml::RoutedEventArgs const &e);
    winrt::fire_and_forget ImportFolderButton_Click(winrt::Windows::Foundation::IInspectable const &sender,
                                                    winrt::Microsoft::UI::Xaml::RoutedEventArgs const &e);

    winrt::event_token SelectionFinished(
        const winrt::Windows::Foundation::TypedEventHandler<vorg_windows::ImportSelectionPage,
                                                            winrt::Windows::Foundation::IInspectable> &handler);
    void SelectionFinished(const winrt::event_token &token);

  private:
    winrt::com_ptr<vorg_windows::implementation::App> mApp{nullptr};
    HWND mHwnd{nullptr};

    winrt::event<winrt::Windows::Foundation::TypedEventHandler<vorg_windows::ImportSelectionPage,
                                                               winrt::Windows::Foundation::IInspectable>>
        mSelectionFinishedEvent;

    void initWndHandle();
};
} // namespace winrt::vorg_windows::implementation

namespace winrt::vorg_windows::factory_implementation
{
struct ImportSelectionPage : ImportSelectionPageT<ImportSelectionPage, implementation::ImportSelectionPage>
{
};
} // namespace winrt::vorg_windows::factory_implementation

M vorg-windows/LandingPage.xaml.cpp => vorg-windows/LandingPage.xaml.cpp +2 -10
@@ 18,6 18,8 @@ namespace winrt::vorg_windows::implementation
LandingPage::LandingPage()
{
    InitializeComponent();
    mApp.copy_from(winrt::get_self<vorg_windows::implementation::App>(
        Application::Current().as<winrt::default_interface<vorg_windows::implementation::App>>()));
}

void LandingPage::openButton_Click(const IInspectable &, const RoutedEventArgs &)


@@ 76,18 78,8 @@ winrt::fire_and_forget LandingPage::launchFileChooser()
    }
}

void LandingPage::initAppPtr()
{
    mApp.copy_from(winrt::get_self<vorg_windows::implementation::App>(
        Application::Current().as<winrt::default_interface<vorg_windows::implementation::App>>()));
}

void LandingPage::initWndHandle()
{
    if (mApp == nullptr)
    {
        initAppPtr();
    }
    auto nativeWindow = mApp->mWindow.try_as<IWindowNative>();
    winrt::check_bool(nativeWindow);
    nativeWindow->get_WindowHandle(&mHwnd);

M vorg-windows/LandingPage.xaml.h => vorg-windows/LandingPage.xaml.h +0 -1
@@ 35,7 35,6 @@ struct LandingPage : LandingPageT<LandingPage>

    // Helper functions
    winrt::fire_and_forget launchFileChooser();
    void initAppPtr();
    void initWndHandle();
};
} // namespace winrt::vorg_windows::implementation

M vorg-windows/Package.appxmanifest => vorg-windows/Package.appxmanifest +1 -1
@@ 9,7 9,7 @@
  <Identity
    Name="a50db69a-6def-418b-8b09-f5d3ab8ea694"
    Publisher="CN=liuha"
    Version="1.0.0.0" />
    Version="1.0.10.0" />

  <Properties>
    <DisplayName>vorg-windows</DisplayName>

M vorg-windows/pch.h => vorg-windows/pch.h +1 -0
@@ 28,6 28,7 @@
#include <winrt/Windows.ApplicationModel.Activation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Media.Core.h>
#include <winrt/Windows.Storage.Pickers.h>
#include <winrt/Windows.UI.Xaml.Interop.h>


M vorg-windows/vorg-windows.vcxproj => vorg-windows/vorg-windows.vcxproj +42 -1
@@ 74,7 74,14 @@
  <ImportGroup Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Label="UserMacros">
    <GenerateAppInstallerFile>False</GenerateAppInstallerFile>
    <AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
    <AppxSymbolPackageEnabled>False</AppxSymbolPackageEnabled>
    <GenerateTestArtifacts>True</GenerateTestArtifacts>
    <AppxBundle>Never</AppxBundle>
    <HoursBetweenUpdateChecks>168</HoursBetweenUpdateChecks>
  </PropertyGroup>
  <ItemDefinitionGroup>
    <ClCompile>
      <PrecompiledHeader>Use</PrecompiledHeader>


@@ 91,6 98,9 @@
      <LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">stdcpp20</LanguageStandard>
      <LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">stdcpp20</LanguageStandard>
    </ClCompile>
    <Link>
      <AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
    <ClCompile>


@@ 121,10 131,18 @@
      <DependentUpon>ErrorContentDialog.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClInclude>
    <ClInclude Include="ImportEditPage.xaml.h">
      <DependentUpon>ImportEditPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClInclude>
    <ClInclude Include="ImportPage.xaml.h">
      <DependentUpon>ImportPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClInclude>
    <ClInclude Include="ImportSelectionPage.xaml.h">
      <DependentUpon>ImportSelectionPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClInclude>
    <ClInclude Include="LandingPage.xaml.h">
      <DependentUpon>LandingPage.xaml</DependentUpon>
      <SubType>Code</SubType>


@@ 149,9 167,15 @@
    <Page Include="ErrorContentDialog.xaml">
      <SubType>Designer</SubType>
    </Page>
    <Page Include="ImportEditPage.xaml">
      <SubType>Designer</SubType>
    </Page>
    <Page Include="ImportPage.xaml">
      <SubType>Designer</SubType>
    </Page>
    <Page Include="ImportSelectionPage.xaml">
      <SubType>Designer</SubType>
    </Page>
    <Page Include="LandingPage.xaml">
      <SubType>Designer</SubType>
    </Page>


@@ 169,10 193,18 @@
      <DependentUpon>ErrorContentDialog.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClCompile>
    <ClCompile Include="ImportEditPage.xaml.cpp">
      <DependentUpon>ImportEditPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClCompile>
    <ClCompile Include="ImportPage.xaml.cpp">
      <DependentUpon>ImportPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClCompile>
    <ClCompile Include="ImportSelectionPage.xaml.cpp">
      <DependentUpon>ImportSelectionPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </ClCompile>
    <ClCompile Include="LandingPage.xaml.cpp">
      <DependentUpon>LandingPage.xaml</DependentUpon>
      <SubType>Code</SubType>


@@ 205,10 237,18 @@
      <DependentUpon>ErrorContentDialog.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Midl>
    <Midl Include="ImportEditPage.idl">
      <DependentUpon>ImportEditPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Midl>
    <Midl Include="ImportPage.idl">
      <DependentUpon>ImportPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Midl>
    <Midl Include="ImportSelectionPage.idl">
      <DependentUpon>ImportSelectionPage.xaml</DependentUpon>
      <SubType>Code</SubType>
    </Midl>
    <Midl Include="LandingPage.idl">
      <DependentUpon>LandingPage.xaml</DependentUpon>
      <SubType>Code</SubType>


@@ 246,6 286,7 @@
  </ItemGroup>
  <ItemGroup>
    <None Include="..\.clang-format" />
    <None Include=".gitignore" />
    <None Include="packages.config" />
  </ItemGroup>
  <ItemGroup>

M vorg-windows/vorg-windows.vcxproj.filters => vorg-windows/vorg-windows.vcxproj.filters +3 -0
@@ 10,6 10,8 @@
    <Page Include="BrowsePage.xaml" />
    <Page Include="ManagePage.xaml" />
    <Page Include="ErrorContentDialog.xaml" />
    <Page Include="ImportEditPage.xaml" />
    <Page Include="ImportSelectionPage.xaml" />
  </ItemGroup>
  <ItemGroup>
    <Midl Include="App.idl" />


@@ 62,6 64,7 @@
  <ItemGroup>
    <None Include="packages.config" />
    <None Include="..\.clang-format" />
    <None Include=".gitignore" />
  </ItemGroup>
  <ItemGroup>
    <Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />

M vorg-windows/vorg-windows.vcxproj.user => vorg-windows/vorg-windows.vcxproj.user +6 -1
@@ 1,4 1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup />
  <PropertyGroup>
    <UapAppxPackageBuildMode>SideloadOnly</UapAppxPackageBuildMode>
    <AppxShowAllApps>False</AppxShowAllApps>
    <AppxBuildConfigurationSelection>x64</AppxBuildConfigurationSelection>
    <PackageOptionalProjectsInIdeBuilds>False</PackageOptionalProjectsInIdeBuilds>
  </PropertyGroup>
</Project>
\ No newline at end of file