Skip to content

Commit

Permalink
version 1
Browse files Browse the repository at this point in the history
  • Loading branch information
José Javier Rodríguez Zas committed Apr 27, 2023
1 parent edb66f6 commit 69c0e5e
Show file tree
Hide file tree
Showing 46 changed files with 1,241 additions and 1 deletion.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,42 @@
<p align="center">
<img src="./imgs/appicon.png" width="150" />
</p>

# whatsapp-no-contact
.NET MAUI app to start sending messages to a WhatsApp number without first adding it as a contact

A [.NET MAUI](https://dotnet.microsoft.com/en-us/apps/maui) app to start sending messages to a WhatsApp number without first adding it as a contact

## Disclaimer

I created this app for my own entertainment and to learn about .NET MAUI. I am not responsible for any damage or malfunction

## About the magic:

```csharp
await Launcher.OpenAsync($"https://wa.me/{phoneNumber}"); // 😜
```

## Building the Windows app (without installer)

```shell
msbuild /restore /t:Publish /p:configuration=Release /p:WindowsAppSDKSelfContained=true /p:Platform="Any CPU" /p:WindowsPackageType=None /p:TargetFramework=net7.0-windows10.0.19041.0 /p:PublishSingleFile=true /p:PublishReadyToRun=false
```

<p align="center">
<img src="./imgs/windows%20dark.png" width="300" />
<img src="./imgs/windows%20light.png" width="300" />
</p>

## Building the Android apk

```shell
dotnet publish -f net7.0-android -c Release
```

<p align="center">
<img src="./imgs/android%20dark.jpg" width="300" />
<img src="./imgs/android%20light.jpg" width="300" />
</p>

---
_thanks to ChatGPT for the icon and helping me juggle fixing some obscure issues_
Binary file added imgs/android dark.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/android light.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/appicon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/windows dark.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/windows light.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions src/WhatsappNoContact.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31611.283
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WhatsappNoContact", "WhatsappNoContact\WhatsappNoContact.csproj", "{4E0A10C4-A938-4FB8-B2E3-221F899216B2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4E0A10C4-A938-4FB8-B2E3-221F899216B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E0A10C4-A938-4FB8-B2E3-221F899216B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E0A10C4-A938-4FB8-B2E3-221F899216B2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{4E0A10C4-A938-4FB8-B2E3-221F899216B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E0A10C4-A938-4FB8-B2E3-221F899216B2}.Release|Any CPU.Build.0 = Release|Any CPU
{4E0A10C4-A938-4FB8-B2E3-221F899216B2}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
EndGlobalSection
EndGlobal
14 changes: 14 additions & 0 deletions src/WhatsappNoContact/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:WhatsappNoContact"
x:Class="WhatsappNoContact.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
30 changes: 30 additions & 0 deletions src/WhatsappNoContact/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace WhatsappNoContact;

public partial class App : Application
{
public App()
{
InitializeComponent();

MainPage = new AppShell();
}

protected override Window CreateWindow(IActivationState activationState)
{

var window = base.CreateWindow(activationState);
#if WINDOWS
const int newWidth = 400;
const int newHeight = 400;

window.Width = newWidth;
window.Height = newHeight;
window.MaximumHeight = newHeight;
window.MaximumWidth = newWidth;
window.MinimumHeight = newHeight;
window.MinimumWidth = newWidth;
#endif
return window;

}
}
14 changes: 14 additions & 0 deletions src/WhatsappNoContact/AppShell.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="WhatsappNoContact.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:WhatsappNoContact"
Shell.FlyoutBehavior="Disabled">

<ShellContent
Title="Whatsapp No Contact"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />

</Shell>
9 changes: 9 additions & 0 deletions src/WhatsappNoContact/AppShell.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace WhatsappNoContact;

public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
}
61 changes: 61 additions & 0 deletions src/WhatsappNoContact/MainPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WhatsappNoContact.MainPage">

<Grid>
<Image Source="{AppThemeBinding Light=bg_light.jpg, Dark=bg_dark.jpg}" Aspect="AspectFill" />

<VerticalStackLayout
Spacing="25"
Padding="30,30"
VerticalOptions="CenterAndExpand"
BackgroundColor="{AppThemeBinding Light=#70707070, Dark=Transparent}"
>

<Label
Text="Enter the phone number:"
SemanticProperties.HeadingLevel="Level3"
SemanticProperties.Description="Enter the phone number (include coutry code)"
FontSize="16"
TextColor="White"
/>
<Label
Margin="0,-25,0,0"
Text="remember to include the coutry code"
SemanticProperties.HeadingLevel="Level9"
FontSize="12"
TextColor="White"
/>

<Entry
x:Name="phoneNumber"
FontSize="25"
Keyboard="Telephone"
TextChanged="OnPhoneNumberTextChanged"
HorizontalTextAlignment="Center"
ClearButtonVisibility="WhileEditing"
Placeholder="Phone number"
Completed="OnStartChatBtnClicked"
IsTextPredictionEnabled="False"
IsSpellCheckEnabled="False"
MaxLength="20"
ReturnType="Go"
TextColor="White"
/>

<Button
x:Name="startChatBtn"
Text="💬 Start chat"
SemanticProperties.Hint="Stat a whatsapp chat with the number entered without creating a contact"
Clicked="OnStartChatBtnClicked"
FontSize="30"
FontAttributes="Bold"
BackgroundColor="#41c151"
TextColor="White"
IsEnabled="False"
/>

</VerticalStackLayout>
</Grid>
</ContentPage>
64 changes: 64 additions & 0 deletions src/WhatsappNoContact/MainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
namespace WhatsappNoContact;

public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
phoneNumber.Focus();
}

async void OnStartChatBtnClicked(object sender, EventArgs e)
{
string input = phoneNumber.Text?.Trim();
if (ValidPhoneNumber(input))
{
ChangeEnabled(false);

// Compute something with the input value
await Launcher.OpenAsync($"https://wa.me/{input}");

ChangeEnabled(true);
}
}

bool ValidPhoneNumber(string input) =>
!string.IsNullOrWhiteSpace(input) &&
input.Length > 1 &&
input.Length <= 20 &&
input.Select((c, idx) => (idx == 0 && c == '+') || char.IsDigit(c)).All(x => x);

bool ValidPhoneNumberCharacters(string input) =>
string.IsNullOrEmpty(input) ||
input[0] == '+' ||
input.Length <= 20 &&
input.Select((c, idx) => (idx == 0 && c == '+') || char.IsDigit(c)).All(x => x);

void ChangeEnabled(bool enabled)
{
phoneNumber.IsEnabled = enabled;
phoneNumber.IsReadOnly = !enabled;
startChatBtn.IsEnabled = enabled;
}


void OnPhoneNumberTextChanged(object sender, TextChangedEventArgs e)
{
// Get the new text value
string newText = e.NewTextValue;

if (string.IsNullOrEmpty(newText))
{
startChatBtn.IsEnabled = false;
return;
}

if (!ValidPhoneNumberCharacters(newText))
{
// If the new text value is not valid, revert to the old text value
phoneNumber.Text = e.OldTextValue;
}

startChatBtn.IsEnabled = ValidPhoneNumber(newText);
}
}
50 changes: 50 additions & 0 deletions src/WhatsappNoContact/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Microsoft.Extensions.Logging;
using Microsoft.Maui.LifecycleEvents;

namespace WhatsappNoContact;

public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});

#if WINDOWS
builder.ConfigureLifecycleEvents(events =>
{
// Make sure to add "using Microsoft.Maui.LifecycleEvents;" in the top of the file
events.AddWindows(windowsLifecycleBuilder =>
{
windowsLifecycleBuilder.OnWindowCreated(window =>
{
window.ExtendsContentIntoTitleBar = false;
var handle = WinRT.Interop.WindowNative.GetWindowHandle(window);
var id = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(handle);
var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(id);
switch (appWindow.Presenter)
{
case Microsoft.UI.Windowing.OverlappedPresenter overlappedPresenter:
//overlappedPresenter.SetBorderAndTitleBar(false, false);
overlappedPresenter.IsMaximizable = false;
overlappedPresenter.IsResizable = false;
break;
}
});
});
});
#endif

#if DEBUG
builder.Logging.AddDebug();
#endif

return builder.Build();
}
}
6 changes: 6 additions & 0 deletions src/WhatsappNoContact/Platforms/Android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
10 changes: 10 additions & 0 deletions src/WhatsappNoContact/Platforms/Android/MainActivity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Android.App;
using Android.Content.PM;
using Android.OS;

namespace WhatsappNoContact;

[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
}
15 changes: 15 additions & 0 deletions src/WhatsappNoContact/Platforms/Android/MainApplication.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Android.App;
using Android.Runtime;

namespace WhatsappNoContact;

[Application]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}

protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#512BD4</color>
<color name="colorPrimaryDark">#2B0B98</color>
<color name="colorAccent">#2B0B98</color>
</resources>
9 changes: 9 additions & 0 deletions src/WhatsappNoContact/Platforms/MacCatalyst/AppDelegate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Foundation;

namespace WhatsappNoContact;

[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

0 comments on commit 69c0e5e

Please sign in to comment.