Skip to content

Commit ca75c89

Browse files
committed
AddContactPage improvements
Added pull to refresh and don't ask Signal about already known Signal contacts I also had to do some upgrades in order for it to work with my version of VS2017/Win10
1 parent e05514f commit ca75c89

File tree

8 files changed

+172
-84
lines changed

8 files changed

+172
-84
lines changed

Signal-Windows.sln

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
21
Microsoft Visual Studio Solution File, Format Version 12.00
32
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26730.3
3+
VisualStudioVersion = 15.0.27004.2002
54
MinimumVisualStudioVersion = 10.0.40219.1
65
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Signal-Windows", "Signal-Windows\Signal-Windows.csproj", "{41736A64-5B66-44AF-879A-501192A46920}"
76
EndProject

Signal-Windows/Models/PhoneContact.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace Signal_Windows.Models
1010
{
1111
public class PhoneContact
1212
{
13+
public string Id { get; set; }
1314
public string Name { get; set; }
1415
public string PhoneNumber { get; set; }
1516
public ImageSource Photo { get; set; }

Signal-Windows/Package.appxmanifest

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@
2020
</uap:DefaultTile>
2121
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="#2090EA" />
2222
</uap:VisualElements>
23+
<Extensions>
24+
<uap:Extension Category="windows.protocol">
25+
<uap:Protocol Name="ms-contact-profile">
26+
<uap:DisplayName>Signal Private Messenger Contact</uap:DisplayName>
27+
</uap:Protocol>
28+
</uap:Extension>
29+
<uap:Extension Category="windows.protocol">
30+
<uap:Protocol Name="ms-ipmessaging">
31+
<uap:DisplayName>Signal Private Messenger Message</uap:DisplayName>
32+
</uap:Protocol>
33+
</uap:Extension>
34+
</Extensions>
2335
</Application>
2436
</Applications>
2537
<Capabilities>

Signal-Windows/Signal-Windows.csproj

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
</PropertyGroup>
9595
<ItemGroup>
9696
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
97-
<None Include="project.json" />
9897
<Content Include="Assets\check.png" />
9998
<Content Include="Assets\double-check.png" />
10099
<Content Include="Assets\gambino.png" />
@@ -308,16 +307,53 @@
308307
<Generator>MSBuild:Compile</Generator>
309308
</Page>
310309
</ItemGroup>
311-
<ItemGroup />
310+
<ItemGroup>
311+
<PackageReference Include="libsignal-service-dotnet">
312+
<Version>2.5.10.3</Version>
313+
</PackageReference>
314+
<PackageReference Include="Microsoft.EntityFrameworkCore">
315+
<Version>1.1.2</Version>
316+
</PackageReference>
317+
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
318+
<Version>1.1.2</Version>
319+
</PackageReference>
320+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite">
321+
<Version>1.1.2</Version>
322+
</PackageReference>
323+
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools">
324+
<Version>1.1.1</Version>
325+
</PackageReference>
326+
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
327+
<Version>6.0.1</Version>
328+
</PackageReference>
329+
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications">
330+
<Version>1.5.1</Version>
331+
</PackageReference>
332+
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
333+
<Version>2.0.0</Version>
334+
</PackageReference>
335+
<PackageReference Include="MvvmLight">
336+
<Version>5.3.0</Version>
337+
</PackageReference>
338+
<PackageReference Include="Nito.AsyncEx">
339+
<Version>4.0.1</Version>
340+
</PackageReference>
341+
<PackageReference Include="QueryString.NET">
342+
<Version>1.0.0</Version>
343+
</PackageReference>
344+
<PackageReference Include="ZXing.Net.Mobile">
345+
<Version>2.2.9</Version>
346+
</PackageReference>
347+
</ItemGroup>
312348
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
313349
<VisualStudioVersion>14.0</VisualStudioVersion>
314350
</PropertyGroup>
315351
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
316-
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
317-
Other similar extension points exist, see Microsoft.Common.targets.
318-
<Target Name="BeforeBuild">
319-
</Target>
320-
<Target Name="AfterBuild">
321-
</Target>
352+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
353+
Other similar extension points exist, see Microsoft.Common.targets.
354+
<Target Name="BeforeBuild">
355+
</Target>
356+
<Target Name="AfterBuild">
357+
</Target>
322358
-->
323359
</Project>

Signal-Windows/ViewModels/AddContactPageViewModel.cs

Lines changed: 93 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ public class AddContactPageViewModel : ViewModelBase
2929
public ObservableCollection<PhoneContact> Contacts;
3030
private List<PhoneContact> signalContacts;
3131
private PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.GetInstance();
32-
private CancellationToken cancellationToken;
32+
public MainPageViewModel MainPageVM;
33+
public AddContactPage View;
3334

3435
private string _ContactName = "";
3536
public string ContactName
@@ -45,21 +46,91 @@ public string ContactNumber
4546
set { _ContactNumber = value; RaisePropertyChanged(nameof(ContactNumber)); }
4647
}
4748

49+
private bool _ContactsVisible = true;
50+
public bool ContactsVisible
51+
{
52+
get { return _ContactsVisible; }
53+
set { _ContactsVisible = value; RaisePropertyChanged(nameof(ContactsVisible)); }
54+
}
55+
56+
private bool _RefreshingContacts = false;
57+
public bool RefreshingContacts
58+
{
59+
get { return _RefreshingContacts; }
60+
set { _RefreshingContacts = value; RaisePropertyChanged(nameof(RefreshingContacts)); }
61+
}
62+
4863
public AddContactPageViewModel()
4964
{
5065
Contacts = new ObservableCollection<PhoneContact>();
5166
signalContacts = new List<PhoneContact>();
5267
}
5368

69+
private bool _UIEnabled = true;
70+
public bool UIEnabled
71+
{
72+
get { return _UIEnabled; }
73+
set { _UIEnabled = value; RaisePropertyChanged(nameof(UIEnabled)); }
74+
}
75+
76+
private bool _AddEnabled = false;
77+
public bool AddEnabled
78+
{
79+
get { return _AddEnabled; }
80+
set { _AddEnabled = value; RaisePropertyChanged(nameof(AddEnabled)); }
81+
}
82+
83+
private bool validName = false;
84+
private bool ValidName
85+
{
86+
get { return validName; }
87+
set
88+
{
89+
validName = value;
90+
SetAddEnabled();
91+
}
92+
}
93+
94+
private bool validNumber = false;
95+
private bool ValidNumber
96+
{
97+
get { return validNumber; }
98+
set
99+
{
100+
validNumber = value;
101+
SetAddEnabled();
102+
}
103+
}
104+
54105
public async Task OnNavigatedTo(CancellationToken? cancellationToken = null)
55106
{
107+
await RefreshContacts(cancellationToken);
108+
}
109+
110+
public async Task RefreshContacts(CancellationToken? cancellationToken = null)
111+
{
112+
RefreshingContacts = true;
113+
Contacts.Clear();
114+
signalContacts.Clear();
56115
SignalServiceAccountManager accountManager = new SignalServiceAccountManager(App.ServiceUrls, App.Store.Username, App.Store.Password, (int)App.Store.DeviceId, App.USER_AGENT);
57116
ContactStore contactStore = await ContactManager.RequestStoreAsync(ContactStoreAccessType.AllContactsReadOnly);
58117
List<PhoneContact> intermediateContacts = new List<PhoneContact>();
59118
if (contactStore != null)
60119
{
61120
HashSet<string> seenNumbers = new HashSet<string>();
62121
var contacts = await contactStore.FindContactsAsync();
122+
ContactAnnotationStore contactAnnotationStore = await ContactManager.RequestAnnotationStoreAsync(ContactAnnotationStoreAccessType.AppAnnotationsReadWrite);
123+
ContactAnnotationList contactAnnotationList;
124+
var contactAnnotationLists = await contactAnnotationStore.FindAnnotationListsAsync();
125+
if (contactAnnotationLists.Count == 0)
126+
{
127+
contactAnnotationList = await contactAnnotationStore.CreateAnnotationListAsync();
128+
}
129+
else
130+
{
131+
contactAnnotationList = contactAnnotationLists[0];
132+
}
133+
63134
foreach (var contact in contacts)
64135
{
65136
var phones = contact.Phones;
@@ -82,6 +153,7 @@ public async Task OnNavigatedTo(CancellationToken? cancellationToken = null)
82153
seenNumbers.Add(formattedNumber);
83154
PhoneContact phoneContact = new PhoneContact
84155
{
156+
Id = contact.Id,
85157
Name = contact.FullName,
86158
PhoneNumber = formattedNumber,
87159
OnSignal = false
@@ -101,61 +173,41 @@ public async Task OnNavigatedTo(CancellationToken? cancellationToken = null)
101173
}
102174
}
103175

176+
// check if we've annotated a contact as a Signal contact already, if we have we don't need to ask Signal about them
177+
for (int i = 0; i < intermediateContacts.Count; i++)
178+
{
179+
var annotatedContact = await contactAnnotationList.FindAnnotationsByRemoteIdAsync(intermediateContacts[i].PhoneNumber);
180+
if (annotatedContact.Count > 0)
181+
{
182+
intermediateContacts[i].OnSignal = true;
183+
signalContacts.Add(intermediateContacts[i]);
184+
intermediateContacts.RemoveAt(i);
185+
i--;
186+
}
187+
}
188+
104189
var signalContactDetails = accountManager.getContacts(intermediateContacts.Select(c => c.PhoneNumber).ToList());
105190
foreach (var contact in intermediateContacts)
106191
{
107192
var foundContact = signalContactDetails.FirstOrDefault(c => c.getNumber() == contact.PhoneNumber);
108193
if (foundContact != null)
109194
{
110195
contact.OnSignal = true;
196+
ContactAnnotation contactAnnotation = new ContactAnnotation();
197+
contactAnnotation.ContactId = contact.Id;
198+
contactAnnotation.RemoteId = contact.PhoneNumber;
199+
contactAnnotation.SupportedOperations = ContactAnnotationOperations.Message | ContactAnnotationOperations.ContactProfile;
200+
await contactAnnotationList.TrySaveAnnotationAsync(contactAnnotation);
111201
signalContacts.Add(contact);
112202
}
113203
}
114204
Contacts.AddRange(signalContacts);
115205
}
116206
else
117207
{
118-
// something something we don't have contact access
119-
}
120-
}
121-
122-
public MainPageViewModel MainPageVM;
123-
public AddContactPage View;
124-
125-
private bool _UIEnabled = true;
126-
public bool UIEnabled
127-
{
128-
get { return _UIEnabled; }
129-
set { _UIEnabled = value; RaisePropertyChanged(nameof(UIEnabled)); }
130-
}
131-
132-
private bool _AddEnabled = false;
133-
public bool AddEnabled
134-
{
135-
get { return _AddEnabled; }
136-
set { _AddEnabled = value; RaisePropertyChanged(nameof(AddEnabled)); }
137-
}
138-
139-
private bool validName = false;
140-
private bool ValidName
141-
{
142-
get { return validName; }
143-
set
144-
{
145-
validName = value;
146-
SetAddEnabled();
147-
}
148-
}
149-
150-
private bool validNumber = false;
151-
private bool ValidNumber
152-
{
153-
get { return validNumber; }
154-
set
155-
{
156-
validNumber = value;
157-
SetAddEnabled();
208+
ContactsVisible = false;
158209
}
210+
RefreshingContacts = false;
159211
}
160212

161213
private void SetAddEnabled()

Signal-Windows/Views/AddContactPage.xaml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
88
xmlns:viewmodels="using:Signal_Windows.ViewModels"
99
xmlns:controls="using:Signal_Windows.Controls"
10+
xmlns:toolbox="using:Microsoft.Toolkit.Uwp.UI.Controls"
1011
mc:Ignorable="d"
1112
DataContext="{Binding AddContactPageInstance, Source={StaticResource Locator}}">
1213

@@ -38,12 +39,20 @@
3839
<Button x:Name="AddButton" Content="Add" IsEnabled="{x:Bind Vm.AddEnabled, Mode=OneWay}" HorizontalAlignment="Stretch" Margin="0,16" Click="AddButton_Click" />
3940
<AutoSuggestBox x:Name="searchBox" VerticalAlignment="Stretch" QueryIcon="Find" TextChanged="searchBox_TextChanged" IsEnabled="{x:Bind Vm.UIEnabled, Mode=OneWay}"/>
4041
</StackPanel>
41-
<ListView x:Name="ContactsList" ItemClick="ContactsList_ItemClick" ItemsSource="{x:Bind Vm.Contacts}" IsItemClickEnabled="True" HorizontalAlignment="Center" IsEnabled="{x:Bind Vm.UIEnabled, Mode=OneWay}" Grid.Row="1" Width="328" Margin="16,0">
42-
<ListView.ItemTemplate>
43-
<DataTemplate>
44-
<controls:AddContactListElement/>
45-
</DataTemplate>
46-
</ListView.ItemTemplate>
47-
</ListView>
42+
<Grid Grid.Row="1" Visibility="{x:Bind Vm.ContactsVisible, Mode=OneWay}">
43+
<toolbox:PullToRefreshListView x:Name="ContactsList" ItemClick="ContactsList_ItemClick" ItemsSource="{x:Bind Vm.Contacts, Mode=OneWay}" IsItemClickEnabled="True" HorizontalAlignment="Center" IsEnabled="{x:Bind Vm.UIEnabled, Mode=OneWay}"
44+
Width="328" Margin="16,0" RefreshRequested="ContactsList_RefreshRequested" IsPullToRefreshWithMouseEnabled="True">
45+
<toolbox:PullToRefreshListView.RefreshIndicatorContent>
46+
<FontIcon Glyph="&#xE72C;" HorizontalAlignment="Center" FontSize="26.667" VerticalAlignment="Bottom"/>
47+
</toolbox:PullToRefreshListView.RefreshIndicatorContent>
48+
<ListView.ItemTemplate>
49+
<DataTemplate>
50+
<controls:AddContactListElement/>
51+
</DataTemplate>
52+
</ListView.ItemTemplate>
53+
</toolbox:PullToRefreshListView>
54+
<ProgressRing Width="75" Height="75" IsActive="{x:Bind Vm.RefreshingContacts, Mode=OneWay}"/>
55+
</Grid>
56+
4857
</Grid>
4958
</Page>

Signal-Windows/Views/AddContactPage.xaml.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,10 @@ private void ContactNumberTextBox_TextChanged(object sender, TextChangedEventArg
6565
{
6666
Vm.ContactNumberTextBox_TextChanged(sender, e);
6767
}
68+
69+
private async void ContactsList_RefreshRequested(object sender, System.EventArgs e)
70+
{
71+
await Vm.RefreshContacts();
72+
}
6873
}
6974
}

Signal-Windows/project.json

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)