Version 3.0.255

This commit is contained in:
Oliver Hauff 2021-11-07 19:42:59 +01:00
parent db9c288584
commit 5a26bf273b
1495 changed files with 159465 additions and 5060 deletions

26
Meinkonrad/TINK/App.xaml Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:themes="clr-namespace:TINK.Themes;assembly=TINKLib"
x:Class="TINK.App">
<Application.Resources>
<ResourceDictionary>
<x:String x:Key="IconMap">&#xf5a0;</x:String>
<x:String x:Key="IconFindBike">&#xf002;</x:String>
<x:String x:Key="IconMyBikes">&#xf206;</x:String>
<x:String x:Key="IconAccount">&#xf007;</x:String>
<x:String x:Key="IconLogin">&#xf2f6;</x:String>
<x:String x:Key="IconSettings">&#xf013;</x:String>
<x:String x:Key="IconFeesAndBikes">&#xf153;</x:String>
<x:String x:Key="IconContact">&#xf095;</x:String>
<x:String x:Key="IconInfo">&#xf05a;</x:String>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here -->
<themes:ShareeBike/>
<!-- Add more resource dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Add more resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>

307
Meinkonrad/TINK/App.xaml.cs Normal file
View file

@ -0,0 +1,307 @@
using System;
using Xamarin.Forms.Xaml;
using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.User.Account;
using Xamarin.Forms;
using Serilog;
using Serilog.Core;
using System.Collections.Generic;
using Serilog.Events;
using TINK.Model.Logging;
using TINK.Model.Device;
using System.Linq;
using MonkeyCache.FileStore;
using Plugin.Connectivity;
using System.Threading;
using TINK.Model.Settings;
using Plugin.Permissions;
using TINK.Services.BluetoothLock.Crypto;
using TINK.Model.Services.Geolocation;
using TINK.Services;
using System.Threading.Tasks;
using TINK.Services.Permissions;
#if ARENDI
using Arendi.BleLibrary.Local;
#endif
// Required for support of binding package, see https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings.
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace TINK
{
public partial class App : Application
{
/// <summary>Title of the attachment file.</summary>
private const string ATTACHMENTTITLE = "Diagnostics.txt";
/// <summary> Model root. </summary>
private static TinkApp m_oModelRoot;
/// <summary>
/// Gets the model root.
/// </summary>
public static TinkApp ModelRoot
{
get
{
if (m_oModelRoot != null)
{
// Root model already exists, nothing to do.
return m_oModelRoot;
}
// Get folder where to read settings from
var specialFolders = DependencyService.Get<ISpecialFolder>();
var internalPersonalDir = specialFolders.GetInternalPersonalDir();
// Delete attachtment from previous session.
DeleteAttachment(internalPersonalDir);
// Setup logger using default settings.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.ControlledBy(new LoggingLevelSwitch { MinimumLevel = Model.Settings.Settings.DEFAULTLOGGINLEVEL })
.WriteTo.Debug()
.WriteTo.File(internalPersonalDir, Model.Logging.RollingInterval.Session)
.CreateLogger();
// Subscribe to any unhandled/ unobserved exceptions.
AppDomain.CurrentDomain.UnhandledException += (sender, unobservedTaskExceptionEventArgs) => { Log.Fatal("Unobserved task exception: {Exception}", unobservedTaskExceptionEventArgs.ExceptionObject); };
TaskScheduler.UnobservedTaskException += (sender, unhandledExceptionEventArgs) => { Log.Fatal("Unhandled exception: {Exception}", unhandledExceptionEventArgs.Exception); };
// Restore last model state from json- file.
Dictionary<string, string> settingsJSON = new Dictionary<string, string>();
try
{
settingsJSON = JsonSettingsDictionary.Deserialize(internalPersonalDir);
}
catch (Exception exception)
{
Log.Error("Reading application settings from file failed.", exception);
}
Model.Settings.Settings settings;
try
{
settings = new Model.Settings.Settings(
JsonSettingsDictionary.GetGroupFilterMapPage(settingsJSON),
JsonSettingsDictionary.GetGoupFilterSettings(settingsJSON),
JsonSettingsDictionary.GetCopriHostUri(settingsJSON),
JsonSettingsDictionary.GetPollingParameters(settingsJSON),
JsonSettingsDictionary.GetMinimumLoggingLevel(settingsJSON),
JsonSettingsDictionary.GetIsReportLevelVerbose(settingsJSON),
JsonSettingsDictionary.GetExpiresAfter(settingsJSON),
JsonSettingsDictionary.GetActiveLockService(settingsJSON),
JsonSettingsDictionary.GetConnectTimeout(settingsJSON),
JsonSettingsDictionary.GetActiveGeolocationService(settingsJSON),
JsonSettingsDictionary.GetCenterMapToCurrentLocation(settingsJSON),
JsonSettingsDictionary.GetLogToExternalFolder(settingsJSON),
JsonSettingsDictionary.GetIsSiteCachingOn(settingsJSON),
JsonSettingsDictionary.GetActiveTheme(settingsJSON) ?? typeof(Themes.Konrad).FullName);
}
catch (Exception exception)
{
Log.Error("Deserializing application settings from dictionary failed.", exception);
settings = new Model.Settings.Settings();
}
if (settings.MinimumLogEventLevel != Model.Settings.Settings.DEFAULTLOGGINLEVEL
|| settings.LogToExternalFolder)
{
// Eigher
// - logging is not set to default value or
// - logging is performed to external folder.
// Need to reconfigure.
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing vialation occurs.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.ControlledBy(new LoggingLevelSwitch(settings.MinimumLogEventLevel))
.WriteTo.Debug()
.WriteTo.File(!settings.LogToExternalFolder ? internalPersonalDir : specialFolders.GetExternalFilesDir(), Model.Logging.RollingInterval.Session)
.CreateLogger();
}
// Get auth cookie
Log.Debug("Get auth cookie.");
IStore store = null;
var lastVersion = JsonSettingsDictionary.GetAppVersion(settingsJSON);
if (lastVersion > new Version(3, 0, 250))
{
// App versions newer than 3.0.173 stored geolocation service in configuration.
// Force a switch to typeof(GeolocationService) for versions < 3.0.251
GeolocationServicesContainer.SetActive(settings.ActiveGeolocationService);
}
store = new Store();
Barrel.ApplicationId = "TINKApp";
var context = SynchronizationContext.Current;
var appInfoService = DependencyService.Get<IAppInfo>();
// Create new app instnace.
Log.Debug("Constructing main model...");
m_oModelRoot = new TinkApp(
settings,
store, // Manages user account
(isConnected, activeUri, sessionCookie, mail, expiresAfter) => ConnectorFactory.Create(isConnected, activeUri, $"sharee.bike/{appInfoService.Version}", sessionCookie, mail, expiresAfter),
GeolocationServicesContainer,
null, /* locksService */
DependencyService.Get<ISmartDevice>(),
specialFolders,
new Cipher(),
null, // Permissions, no more used.
#if ARENDI
DependencyService.Get<ICentral>(),
#else
null,
#endif
isConnectedFunc: () => CrossConnectivity.Current.IsConnected,
postAction: (d, obj) => context.Post(d, obj),
currentVersion: appInfoService.Version,
lastVersion: JsonSettingsDictionary.GetAppVersion(settingsJSON),
whatsNewShownInVersion: JsonSettingsDictionary.GetWhatsNew(settingsJSON) ?? settingsJSON.GetAppVersion());
Log.Debug("Main model successfully constructed.");
return m_oModelRoot;
}
}
/// <summary>
/// Entry point of application.
/// </summary>
public App()
{
InitializeComponent();
#if USEFLYOUT
// Use flyout page.
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.Root.RootPage()) // Show whats new info.
: (Page)new View.Root.RootPage(); // Just start sharee- app
#else
// Use shell.
MainPage = ModelRoot.WhatsNew.IsShowRequired
? new View.WhatsNew.WhatsNewPage(() => MainPage = new View.RootShell.AppShell()) // Show whats new info.
: (Page)new View.RootShell.AppShell(); // Just start sharee- app
#endif
}
/// <summary> Concatenates all log files to a single one. </summary>
/// <returns>Full file name of attachment.</returns>
public static string CreateAttachment()
{
var sessionLogFiles = Log.Logger.GetLogFiles().ToArray();
if (sessionLogFiles.Length < 1)
{
// Either
// - there is no logging file
// - an error occurred getting list of log files.
return string.Empty;
}
var fullLogFileName = System.IO.Path.Combine(ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
// Stop logging to avoid file access exception.
Log.CloseAndFlush();
System.IO.File.WriteAllLines(
fullLogFileName,
sessionLogFiles.SelectMany(name =>
(new List<string> { $"{{\"SessionFileName\":\"{name}\"}}" })
.Concat(System.IO.File.ReadLines(name).ToArray())));
// Resume logging
Log.Logger = new LoggerConfiguration()
.MinimumLevel.ControlledBy(new LoggingLevelSwitch { MinimumLevel = ModelRoot.Level.MinimumLevel })
.WriteTo.Debug()
.WriteTo.File(ModelRoot.LogFileParentFolder, Model.Logging.RollingInterval.Session)
.CreateLogger();
return fullLogFileName;
}
/// <summary>Deletes an attachment if there is one.</summary>
/// <param name="folder">Folder to delete, is null folder is queried from model.</param>
private static void DeleteAttachment(string folder = null)
{
var attachment = System.IO.Path.Combine(folder ?? ModelRoot.LogFileParentFolder, ATTACHMENTTITLE);
if (!System.IO.File.Exists(attachment))
{
// No attachment found.
return;
}
System.IO.File.Delete(attachment);
}
protected override void OnSleep()
{
// Handle when your app sleeps
Log.CloseAndFlush();
}
protected override void OnResume()
{
DeleteAttachment();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.ControlledBy(new LoggingLevelSwitch { MinimumLevel = ModelRoot.Level.MinimumLevel })
.WriteTo.Debug()
.WriteTo.File(ModelRoot.LogFileParentFolder, Model.Logging.RollingInterval.Session)
.CreateLogger();
}
/// <summary> Gets the current logging level.</summary>
/// <returns></returns>
private static LogEventLevel GetCurrentLogEventLevel()
{
foreach (LogEventLevel level in Enum.GetValues(typeof(LogEventLevel)))
{
if (Log.IsEnabled(level))
return level;
}
return LogEventLevel.Error;
}
/// <summary>
/// Holds the permission service instance.
/// </summary>
private static ILocationPermission _PermissionsService = null;
/// <summary>
/// Service to manage permissions (location) of the app.
/// </summary>
public static ILocationPermission PermissionsService
{
get
{
if (_PermissionsService != null)
return _PermissionsService;
_PermissionsService = new Services.Permissions.Plugin.Permissions();
return _PermissionsService;
}
}
/// <summary>
/// Service to manage bluetooth stack.
/// </summary>
public static Plugin.BLE.Abstractions.Contracts.IBluetoothLE BluetoothService => Plugin.BLE.CrossBluetoothLE.Current;
/// <summary>
/// Service container to manage geolocation services.
/// </summary>
public static IServicesContainer<IGeolocation> GeolocationServicesContainer { get; }
= new ServicesContainerMutable<IGeolocation>(
new HashSet<IGeolocation> {
new LastKnownGeolocationService(DependencyService.Get<IGeolodationDependent>()),
new SimulatedGeolocationService(DependencyService.Get<IGeolodationDependent>()),
new GeolocationService(DependencyService.Get<IGeolodationDependent>()) },
Model.Settings.Settings.DefaultLocationService.FullName);
}
}

View file

@ -0,0 +1,38 @@
using System.Linq;
using TINK.View.Map;
using TINK.ViewModel.Map;
using Xamarin.Forms;
namespace TINK
{
public static class BackdoorMethodHelpers
{
public static void DoTapPage(string stationId )
{
Serilog.Log.Information($"Request via backdoor to tap station {stationId}.");
var currentPage = GetCurrentPage();
var mapPageViewModel = (currentPage as MapPage)?.BindingContext as MapPageViewModel;
if (mapPageViewModel == null)
{
Serilog.Log.Error($"Request via backdoor to tap station {stationId} aborted because current page is not of expected type {typeof(MapPage).Name}. Type detected is {currentPage.GetType().Name}.");
return;
}
Serilog.Log.Information($"Invoking member to tap.");
mapPageViewModel?.OnStationClicked(stationId);
}
/// <summary> Gets the current page assumed that app is master detail page.</summary>
/// <returns></returns>
static Page GetCurrentPage()
{
#if USEFLYOUT
return (Application.Current.MainPage as FlyoutPage)?.Detail.Navigation.NavigationStack.LastOrDefault();
#else
return (Application.Current.MainPage as AppShellViewModel)?.Detail.Navigation.NavigationStack.LastOrDefault();
#endif
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,78 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK Konstanz</title>
<base href="https://tink-konstanz.de/TINK-Konstanz/Transportr%C3%A4der" />
<meta name="google-site-verification" content="_APrJWq--w-a4cD3sqOin3stmcxCvHpAVhV35E2sRnU" />
<meta name="viewport" content="width=device-width,target-densitydpi=device-dpi,initial-scale=1,user-scalable=yes" />
<meta name="description" content="Die TINK Konstanz Transporträder sind an ihren Stationen in den Stadtteilen Altstadt, Paradies und Petershausen aktuell mittels SMS anzumieten." />
<meta name="keywords" content="TINK, Konstanz, Transportrad, Lastenrad, Leihrad, Mieten, fahrradspezialitäten" />
<meta name="author" content="Dominik Langer" />
<meta name="copyright" content="Dominik Langer" />
<meta name="publisher" content="Dominik Langer" />
<link rel="manifest" href="" />
<link rel="shortcut icon" href="https://www2.tink-konstanz.de/img/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto+Condensed" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://www2.tink-konstanz.de/css/local_style.css");
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="">
<div class='container'>
<div id='Contenttxt'>
<div class="content_title2" id="2350">Impressum</div>
<div style=""></div>
<div class="content2_contact">Angaben gemäß § 5 TMG:<br /><br />
Dominik Langer<br />
Fahrradspezialitäten<br />
Marie-Curie-Str.1<br />
79100 Freiburg<br /><br />
eMail: tink@fahrradspezialitaeten.com<br />
Tel.: 07531-3694389<br /> <br />
Umsatzsteuer-Identifikationsnummer gemäß §27 a Umsatzsteuergesetz:<br />
Umsatzsteuer-ID: DE815422380<br /><br />
Screendesign: Sebastian Krämer <a href='http://www.kartoffeldruck-media.de' target='_blank'>www.kartoffeldruck-media.de</a><br />
Programmierung: Rainer Gümpelein <a href='http://www.GNU-Systems.de' target='_blank'>www.GNU-Systems.de</a><br />
App: O. Hauff, gruks@posteo.eu<br /><br />
Irrtümer, Druck-/Schreibfehler, Preisänderungen und Liefermöglichkeit vorbehalten.<br /><br />
<span class='content1'>Haftungsausschluss (Disclaimer)</span><br /><br />
<span style='font-weight:bold'>Haftung für Inhalte</span><br />
Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.<br /><br />
<span style='font-weight:bold'>Haftung für Links</span><br />
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.<br /><br />
Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten durch Dritte zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit ausdrücklich widersprochen. Die Betreiber der Seiten behalten sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-Mails, vor.<br /><br /> <br />
<div style="clear:both;"></div>
<div class="content2_contact">&nbsp;</div>
</div>
</div>
<div style='width:100%;background-color:#0061a1;'>
<div class='container'>
<div style="float:left;padding:30px 0 0 7px;"><a target="_blank" href="https://www.facebook.com/tink.bike"><img style="height:50px;" src="https://www2.tink-konstanz.de/img/footerFacebook.png" /></a></div>
<div style="float:left;padding:30px 0 0 20px;"><a href="http://tink.bike" target="_blank"><img style="height:50px;" src="https://www2.tink-konstanz.de/img/footerTink.png" /></a></div>
<div style="float:left;color:white;font-size:0.91em;padding:30px 15px 0 25px;width:330px;">TINK ist ein Angebot der Stadt Konstanz und ihrer Partner an alle Bürgerinnen und Bürger sowie Gäste der Stadt. TINK wird in den Pilotstädten Konstanz und Norderstedt gefördert vom Bundesministerium für Verkehr und digitale Infrastruktur (BMVI) im Rahmen des Nationalen Radverkehrsplans 2020 (NRVP).</div>
<div style="clear:both;float:left;padding:30px 0 0 7px;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer1_Bund.png" /></div>
<div style="float:left;padding:30px 0 0 0;"><img src="https://www2.tink-konstanz.de/img/footer2_fahrradspezialitaeten.png" style="height:105px;" /></div>
<div style="float:left;padding:30px 0 0 0;"><img src="https://www2.tink-konstanz.de/img/footer3_Konstanz.png" style="height:105px;" /></div>
<div style="float:left;padding:30px 0 0 0;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer3.1_Sponsoren.png" /></div>
<div style="float:left;padding:30px 0 0 0;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer4_ideelle_Partner.png" /></div>
<div style="clear:both;height:30px;width:100%;">&nbsp;</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,567 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK-App</title>
<base href="https://tink-konstanz.de/TINK-Konstanz/Transportr%C3%A4der" />
<meta name="viewport" content="width=device-width,target-densitydpi=device-dpi,initial-scale=1,user-scalable=yes" />
<link rel="manifest" href="" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto+Condensed" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://www2.tink-konstanz.de/css/local_style.css");
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div class='container'>
<div id='Contenttxt'>
<div class="content_title2">Version</div>
<div style=""></div>
<br />Version der installierten TINK- App: <b>CURRENT_VERSION_TINKAPP</b>.
<div class="content_title2">Entwickler</div>
<div style=""></div>
<br />Programmierung TINK- App: O. Hauff, gruks@posteo.eu.<br />
<div class="content_title2">Verwendete Bibliotheken</div>
<div style=""></div>
<br />
<table>
<tr><td>Paket </td><td>Lizenz </td></tr>
<tr><td>Newtonsoft Json.NET von James Newton-King </td><td><a href="#MITLicense2007">MIT Lizenz 2007</a> </td></tr>
<tr><td>PCLCrypto von AArnott </td><td><a href="#MSPL_Long">Microsoft Public License(Ms-PL)</a></td></tr>
<tr><td>PCLStorage von Daniel Plaisted </td><td><a href="#MSPL_Long">Microsoft Public License (Ms-PL)</a></td></tr>
<tr><td>Pinvoke von AArnott </td><td><a href="#MITLicenseAArnott">MIT- Lizenz für Pinvoke</a></td></tr>
<tr><td>Serilog. </td><td><a href="#ApacheLicense2004">Apache License</a></td></tr>
<tr><td>Validation von AArnott </td><td><a href="#MSPL_Short">Microsoft Public License (MS-PL)</a></td></tr>
<tr><td>Xamarin.Forms.GoogleMaps von amay077 </td><td><a href="#MITLicense2016_2017">MIT Lizenz 2016- 2017 </a> </td></tr>
<tr><td>Xam.Plugins.Messaging von Carel Lotz </td><td><a href="#MITLicense2014">MIT Lizenz 2014</a> </td></tr>
<tr><td>MonkeyCache von James Montemagno </td><td><a href="#MITLicense2018">MIT Lizenz 2018</a> </td></tr>
<tr><td>Xam.Plugin.Connectivity von James Montemagno </td><td><a href="#MITLicense2016">MIT Lizenz 2016</a> </td></tr>
</table>
<div class="content_title2">Lizenzen</div>
<div style=""></div>
<article id="ApacheLicense2004">
<div class="content2">
<span class='content1'>Apache License</span><br />
<p>Version 2.0, January 2004</p>
<p>www.apache.org</p>
<p>TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION</p>
<p>
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
</p>
<p>
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
</p>
<p>
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
</p>
<p>
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
</p>
<p>
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
</p>
<p>
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
</p>
<p>
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
</p>
<p>
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
</p>
<p>
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
</p>
<p>
END OF TERMS AND CONDITIONS
</p>
<p>
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
<a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</p>
</div>
</article>
<article id="MSPL_Long">
<div class="content2">
<span class='content1'>Microsoft Public License (Ms-PL)</span><br />
<p>
This license governs use of the accompanying software. If you use the software,
you accept this license. If you do not accept the license, do not use the
software.
</p>
<p>1. Definitions</p>
<p>
The terms "reproduce," "reproduction," "derivative works," and "distribution"
have the same meaning here as under U.S. copyright law.
</p>
<p>
A "contribution" is the original software, or any additions or changes to the
software.
</p>
<p>
A "contributor" is any person that distributes its contribution under this
license.
</p>
<p>
"Licensed patents" are a contributor's patent claims that read directly on its
contribution.
</p>
<p>2. Grant of Rights</p>
<p>
(A) Copyright Grant- Subject to the terms of this license, including the license
conditions and limitations in section 3, each contributor grants you a
non-exclusive, worldwide, royalty-free copyright license to reproduce its
contribution, prepare derivative works of its contribution, and distribute its
contribution or any derivative works that you create.
</p>
<p>
(B) Patent Grant- Subject to the terms of this license, including the license
conditions and limitations in section 3, each contributor grants you a
non-exclusive, worldwide, royalty-free license under its licensed patents to
make, have made, use, sell, offer for sale, import, and/or otherwise dispose of
its contribution in the software or derivative works of the contribution in the
software.
</p>
<p>3. Conditions and Limitations</p>
<p>
(A) No Trademark License- This license does not grant you rights to use any
contributors' name, logo, or trademarks.
</p>
<p>
(B) If you bring a patent claim against any contributor over patents that you
claim are infringed by the software, your patent license from such contributor
to the software ends automatically.
</p>
<p>
(C) If you distribute any portion of the software, you must retain all
copyright, patent, trademark, and attribution notices that are present in the
software.
</p>
<p>
(D) If you distribute any portion of the software in source code form, you may
do so only under this license by including a complete copy of this license with
your distribution. If you distribute any portion of the software in compiled or
object code form, you may only do so under a license that complies with this
license.
</p>
<p>
(E) The software is licensed "as-is." You bear the risk of using it. The
contributors give no express warranties, guarantees or conditions. You may have
additional consumer rights under your local laws which this license cannot
change. To the extent permitted under your local laws, the contributors exclude
the implied warranties of merchantability, fitness for a particular purpose and
non-infringement.
</p>
</div>
</article>
<article id="MSPL_Short">
<div class="content2">
<span class='content1'>Microsoft Public License (MS-PL)</span><br />
<p>
This license governs use of the accompanying software. If you use the software, you
accept this license. If you do not accept the license, do not use the software.
</p>
<p>1. Definitions</p>
<p>
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
</p>
<p>2. Grant of Rights</p>
<p>
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
</p>
<p>
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
</p>
<p>3. Conditions and Limitations</p>
<p>
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
</p>
<p>
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
</p>
<p>
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
</p>
<p>
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
</p>
<p>
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
</p>
</div>
</article>
<article id="MITLicenseAArnott">
<div class="content2">
<span class='content1'>MIT- Lizenz für Pinvoke von AArnott</span><br />
<p>
The following license applies to all files in this project unless specified otherwise
within individual files.
See also the COPYRIGHT.md file.
</p>
<p>The MIT License (MIT)</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
</p>
</div>
</article>
<article id="MITLicense2007">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>Copyright (c) 2007 James Newton-King</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the /"Software/"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</p>
</div>
</article>
<article id="MITLicense2014">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>Copyright (c) 2014 Carel Lotz</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</p>
</div>
</article>
<article id="MITLicense2016_2017">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>Copyright (c) amay077 2016 - 2017</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</p>
</div>
</article>
<article id="MITLicense2018">
<div class="content2">
<span class='content1'>MIT License</span><br />
<p>Copyright (c) 2018 James Montemagno</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</p>
</div>
</article>
<article id="MITLicense2016">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>Copyright (c) 2016 James Montemagno / Refractored LLC</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</p>
</div>
</article>
</div>
</div>
<div style='width:100%;background-color:#0061a1;'>
<div class='container'>
<div style="float:left;padding:30px 0 0 7px;"><a target="_blank" href="https://www.facebook.com/tink.bike"><img style="height:50px;" src="https://www2.tink-konstanz.de/img/footerFacebook.png" /></a></div>
<div style="float:left;padding:30px 0 0 20px;"><a href="http://tink.bike" target="_blank"><img style="height:50px;" src="https://www2.tink-konstanz.de/img/footerTink.png" /></a></div>
<div style="float:left;color:white;font-size:0.91em;padding:30px 15px 0 25px;width:330px;">TINK ist ein Angebot der Stadt Konstanz und ihrer Partner an alle Bürgerinnen und Bürger sowie Gäste der Stadt. TINK wird in den Pilotstädten Konstanz und Norderstedt gefördert vom Bundesministerium für Verkehr und digitale Infrastruktur (BMVI) im Rahmen des Nationalen Radverkehrsplans 2020 (NRVP).</div>
<div style="clear:both;float:left;padding:30px 0 0 7px;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer1_Bund.png" /></div>
<div style="float:left;padding:30px 0 0 0;"><img src="https://www2.tink-konstanz.de/img/footer2_fahrradspezialitaeten.png" style="height:105px;" /></div>
<div style="float:left;padding:30px 0 0 0;"><img src="https://www2.tink-konstanz.de/img/footer3_Konstanz.png" style="height:105px;" /></div>
<div style="float:left;padding:30px 0 0 0;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer3.1_Sponsoren.png" /></div>
<div style="float:left;padding:30px 0 0 0;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer4_ideelle_Partner.png" /></div>
<div style="clear:both;height:30px;width:100%;">&nbsp;</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,64 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK Konstanz</title>
<base href="https://tink-konstanz.de/TINK-Konstanz/Transportr%C3%A4der" />
<meta name="google-site-verification" content="_APrJWq--w-a4cD3sqOin3stmcxCvHpAVhV35E2sRnU" />
<meta name="viewport" content="width=device-width,target-densitydpi=device-dpi,initial-scale=1,user-scalable=yes" />
<meta name="description" content="Die TINK Konstanz Transporträder sind an ihren Stationen in den Stadtteilen Altstadt, Paradies und Petershausen aktuell mittels SMS anzumieten." />
<meta name="keywords" content="TINK, Konstanz, Transportrad, Lastenrad, Leihrad, Mieten, fahrradspezialitäten" />
<meta name="author" content="Dominik Langer" />
<meta name="copyright" content="Dominik Langer" />
<meta name="publisher" content="Dominik Langer" />
<link rel="manifest" href="" />
<link rel="shortcut icon" href="https://www2.tink-konstanz.de/img/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto+Condensed" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://www2.tink-konstanz.de/css/local_style.css");
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="">
<div class='container'>
<div id='Contenttxt'>
<div class="content_title2" id="2344">WIE FUNKTIONIERT DAS TRANSPORTRAD-MIETEN?</div>
<div style=""></div>
<div class="content2">
<span class='content1'>Erstmalige Registrierung</span><br />Vor der ersten Anmietung eines Transportrades ist es notwendig, sich kostenlos als Nutzerin oder Nutzer zu registrieren. Das dauert nur wenige Minuten und geht am einfachsten über den <a href='https://tink-konstanz.de/TINK-Konstanz/Mieten'>Mieten</a> Button. Sobald der Account freigeschaltet ist, kann es losgehen.<br /><br />
<span class='content1'>Transportrad mieten</span><br />Mit der TINK- App Rad an der nächsten TINK Station reservieren (freie Räder siehe Ansicht "Fahrradstandorte") oder den Code für das Zahlenschloss mittels SMS anfordern. Die Anleitung, wie dies genau geht, findet sich auf nebenstehendem Reiter "Räder" oder direkt an den Stationen, auf den Rädern.<br />
<span style='font-weight:bold'>&bull; Hinweis:</span> Zusätzliche Fahrräder, die nicht in der Ansicht "Farradstandorte" angezeigt werden (da noch nicht mit Bordcomputer ausgestattet), finden sich auf <a href="https://tink-konstanz.de/">tink-konstanz.de/</a> am Seitenende.<br />
<span style='font-weight:bold'>&bull; Wichtig:</span> Nach der Nutzung das Rad an eine der TINK Stationen zurückbringen, an der Station anschließen und Anschließen über Bordcomputer bestätigen oder mittels SMS ausloggen.<br />
<br /><br /><span class='content1'>Preise</span><br />Die erste Stunde pro Tag ist kostenfrei, danach kostet jede weitere halbe Stunde 1 Euro. Maximal kostet ein Rad pro 24 Stunden 9 Euro. Es können maximal drei Räder pro Account gemietet werden. Bezahlung per Abbuchung oder Kreditkarte.<br />Servicegebühren: Bei Abstellen eines Rades außerhalb der Stationen werden entfernungsabhängige Gebühren für die Rückführung berechnet. Aktuelle Preisliste siehe AGBs.
</div>
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div id="2358" class="content_title2">WELCHE TRANSPORTRÄDER GIBT ES BEI TINK?</div>
<div style=""></div>
<div class="content2"><span class='content1'>Zweirädriges Transportrad mit Platz für zwei Getränkekisten, Zuladung bis 80 kg. <br />Dreirädriges Transportrad sogar mit Platz für vier Getränkekisten, Zuladung bis 100 kg.</span><br />Jedes Rad verfügt über eine leichtgängige Achtgang-Schaltung und einen höhenverstellbaren Sattel. Im Zweirad können 2 Kinder, im Dreirad sogar 4 Kinder bis 6 Jahre mitgenommen werden. Die wegklappbaren Kindersitze verfügen über Sicherheitsgurte.<br />Die Räder sind nach etwas Gewöhnung leicht und sicher zu fahren. Vor der ersten Nutzung empfehlen wir ein kurzes Üben ohne Beladung abseits des Straßenverkehrs. Einfach mal ausprobieren, es macht richtig Spaß!<br /><span>&nbsp;</span></div>
<img src="https://www2.tink-konstanz.de/data/200001-resize/2358/TINK Papa Kind_RZ.jpg:282:188.jpg" id="pic-float" />
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200001-resize/2358/TINK_Jan_Krissi_Imperia_RZ.jpg:188:188.jpg" />
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200001-resize/2358/TINK_Krissi_Hafen_RZ.jpg:282:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
</div>
</div>
<div style='width:100%;background-color:#0061a1;'>
<div class='container'>
<div style="float:left;padding:30px 0 0 7px;"><a target="_blank" href="https://www.facebook.com/tink.bike"><img style="height:50px;" src="https://www2.tink-konstanz.de/img/footerFacebook.png" /></a></div>
<div style="float:left;padding:30px 0 0 20px;"><a href="http://tink.bike" target="_blank"><img style="height:50px;" src="https://www2.tink-konstanz.de/img/footerTink.png" /></a></div>
<div style="float:left;color:white;font-size:0.91em;padding:30px 15px 0 25px;width:330px;">TINK ist ein Angebot der Stadt Konstanz und ihrer Partner an alle Bürgerinnen und Bürger sowie Gäste der Stadt. TINK wird in den Pilotstädten Konstanz und Norderstedt gefördert vom Bundesministerium für Verkehr und digitale Infrastruktur (BMVI) im Rahmen des Nationalen Radverkehrsplans 2020 (NRVP).</div>
<div style="clear:both;float:left;padding:30px 0 0 7px;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer1_Bund.png" /></div>
<div style="float:left;padding:30px 0 0 0;"><img src="https://www2.tink-konstanz.de/img/footer2_fahrradspezialitaeten.png" style="height:105px;" /></div>
<div style="float:left;padding:30px 0 0 0;"><img src="https://www2.tink-konstanz.de/img/footer3_Konstanz.png" style="height:105px;" /></div>
<div style="float:left;padding:30px 0 0 0;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer3.1_Sponsoren.png" /></div>
<div style="float:left;padding:30px 0 0 0;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer4_ideelle_Partner.png" /></div>
<div style="clear:both;height:30px;width:100%;">&nbsp;</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,141 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK Konstanz</title>
<base href="https://tink-konstanz.de/TINK-Konstanz/Anleitungen" />
<meta name="copyright" content="Dominik Langer" />
<meta name="publisher" content="Dominik Langer" />
<meta name="author" content="Dominik Langer" />
<meta name="keywords" content="TINK, Konstanz, Transportrad, Lastenrad, Leihrad, Mieten, fahrradspezialitäten" />
<meta name="google-site-verification" content="_APrJWq--w-a4cD3sqOin3stmcxCvHpAVhV35E2sRnU" />
<meta name="description" content="Die TINK Konstanz Transporträder sind an ihren Stationen in den Stadtteilen Altstadt, Paradies und Petershausen aktuell mittels SMS anzumieten." />
<meta name="viewport" content="width=device-width,target-densitydpi=device-dpi,initial-scale=1,user-scalable=yes" />
<link href="" rel="manifest" />
<link type="image/x-icon" rel="shortcut icon" href="https://www2.tink-konstanz.de/img/favicon.ico" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto+Condensed" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://www2.tink-konstanz.de/css/local_style.css");
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="">
<div class='container'>
<div id='Contenttxt'>
<div id="3401" class="content_title2">Anleitung Mietvorgang für registrierte Nutzerinnen und Nutzer</div>
<div style=""></div>
<div class="content2">
<span class='content12'>1. Rad mieten</span><br /><br />
<span style='font-weight:bold;'>a) per TINK- App</span><br />• auf grünes Stationssymbol in der TINK- App Ansicht "Fahrradstandorte" tippen.<br />• in der Stationsansicht, die nach dem Antippen des Stationssymbols automatisch geöffnet wird, werden alle verfügbaren Räder angezeigt.<br />• Transportrad, das gemietet werden soll, antippen.<br />• die Frage, ob das Rad reserviert werden soll, mit "JA" beantworten.<br />• jetzt wird neben dem Fahrrad der Zahlencode für das Fahrrad angezeigt.<br />• Bordcomputer mit Taste 0 aktivieren und Zahlencode eingeben. Schloss öffnet automatisch.<br />Das Rad ist erst gemietet, sobald Sie den Zahlencode eingegeben haben. Falls Sie das nicht tun, dann verfällt der Code nach 15 Minuten.<br /><br />
<span style='font-weight:bold;'>b) per SMS</span> (um diesen Service nutzen zu können muss ihre Mobiltelefonnummer in ihrem Account hinterlegt sein)<br />• SMS mit der Radnummer (am Rahmen unterhalb des Sattels) an die 0176 43852920 versenden<br />• Antwort-SMS mit vierstelligem Code abwarten<br />• Bordcomputer mit Taste 0 aktivieren und Zahlencode eingeben. Schloss öffnet automatisch.<br />Das Rad ist erst gemietet, sobald Sie den Zahlencode eingegeben haben. Falls Sie das nicht tun verfällt der Code nach 15 Minuten.<br /><br />Falls das Fahrrad keinen Bordcomputer besitzt oder dieser deaktiviert ist, wird das Rad mit einem Zahlenschloss gesichert. Mit dem übermittelten Code können Sie das Zahlenschloss des Rades öffnen und losradeln. Das Rad ist in diesem Fall von Ihnen gemietet, sobald Sie die Antwort-SMS mit dem Zahlencode erhalten haben.<br /><br />
<span style='font-weight:bold;'>c) per Chip</span><br />• Bordcomputer mit Taste 0 aktivieren<br />• RFID Chip an markierter Stelle (rechts neben der Tastatur) anhalten<br />• Sobald der RFID Chip erkannt ist öffnet das Schloss automatisch.<br /><br /><span class='content12'>2. Die Fahrt unterbrechen</span><br /><br />• Bei Abstellen des Rades bitte die Funktion Parken über den Bordcomputer nutzen.<br />• Das Schloss lässt sich verschließen und mit dem dem vorhandenen Code wieder öffnen<br /><br /><span class='content12'>3. Rad zurückgeben</span><br /><br /><span style='font-weight:bold;'>a) mit Bordcomputer</span><br />• Rad an eine TINK-Station stellen<br />• Funktion Rückgabe wählen indem Sie die Taste 2 drücken<br />• Frage über Defekt des Rades beantworten<br />• Ankerseil einhängen und Schloss per Hand verriegeln<br />• Durch Eingabe der 1 am Bordcomputer bestätigen dass das Schloss verriegelt ist<br />• Der Mietvorgang ist nun beendet<br /><br /><span style='font-weight:bold;'>b) mit Zahlenschloss</span><br />• Rad an eine TINK-Station stellen<br />• Mit Zahlenschloss und Ankerseil anschließen<br />• Stationsnummer oben auf dem TINK Schild ablesen<br />• SMS an die 0176 43852920 mit folgendem Inhalt versenden: Schlosscode, Stationsnummer<br />• Rückgabebestätigung abwarten<br />• Rad steht für nächste Nutzerin/ nächsten Nutzer zur Verfügung
</div>
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div id="3402" class="content_title2">Zweirädriges TINK Rad: Hochklappen des Fahrradständers</div>
<div style=""></div>
<div class="content2">So abgestellt hat das zweirädrige Transportrad<br />einen sicheren Stand.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3402/image.4HJ5PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Zum Weiterfahren das Transportrad nach vorne bewegen,<br />bis kein Gewicht mehr auf dem Fahrradständer liegt.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3403/image.RIX2PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Den Fahrradständer mit dem Fuß nach oben drücken, bis er<br />hörbar am Magneten (Pfeil) einrastet. So fällt er unterwegs nicht<br />herunter.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3404/image.FDR7PY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div class="content_title2" id="3406">Dreirädriges TINK Rad: Lösen und Aktivieren der Feststellbremse</div>
<div style=""></div>
<div class="content2">Die Feststellbremse ist der graue Stift, der aus der Bremse<br />herausragt. Ist sie aktiv, kann das Dreirad nicht wegrollen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3406/image.HZ17PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Lösen der Feststellbremse: Die Bremse vollständig anziehen, bis<br />der Stift wieder auf seine ursprüngliche Position herausspringt.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3407/image.1YBAQY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Aktivieren der Feststellbremse: Die Bremse vollständig anziehen<br />und den Stift hineindrücken.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3408/image.FJM2PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div class="content_title2" id="3409">Höhenregulierung des Sattels</div>
<div style=""></div>
<div class="content2">Hier im Bild ist der Hebel zum Einstellen des Sattels zu sehen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3409/image.ZQ65PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Durch Drücken des Hebels ist die Sattelhöhe frei verstellbar.<br />Vergleichbar mit einem Bürostuhl bewegt sich der Sattel<br />automatisch nach oben.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3410/image.QQZCQY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Durch kräftiges Herunterdrücken des Sattels (und gleichzeitigem Betätigen des Hebels) kann der Sattel nach unten verstellt werden. Tipp: Eventuell draufsetzen und dann den Hebel betätigen, um den Sattel nach unten zu drücken.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3411/image.NQ5FQY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div class="content_title2" id="3412">Verbinden des Kindergurts</div>
<div style=""></div>
<div class="content2">Der Gurt besteht aus drei Einzelteilen. Zunächst die oberen<br />beiden Einzelstücke nehmen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3412/image.4XWCQY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Die beiden Einzelstücke zusammenfügen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3413/image.X3F1PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Das obere und untere Teilstück verbinden (bis zum Einrasten).<br />Lösen der Teilstücke durch Drücken auf den roten Knopf.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3414/image.DYOXPY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div id="3415" class="content_title2">Anschließen des Transportrades</div>
<div style=""></div>
<div class="content2">Für das richtige Anschließen des Transportrades wird das<br />Sicherungsseil (hängt an der Station) und das Zahlenschloss<br />benötigt. Das Zahlenschloss bleibt immer beim Rad!</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3415/image.IRL8PY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Das Schloss durch die Schlaufe des Sicherheitsseiles ziehen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3416/image.831ZPY.png:354:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Das Schloss um das Hinterrad und den Rahmen schließen. Sollte kein<br />Sicherheitsseil mehr verfügbar sein (weil bereits mindestens drei<br />Transporträder an der Station stehen), dann das Zahlenschloss einfach<br />ohne Sicherungsseil um das Hinterrad und den Rahmen schließen, wenn<br />möglich an eine Stütze der Station.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3418/image.J6NIQY.png:333:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div class="content_title2" id="3419">Rückmeldungen und Fragen an info@tink.bike</div>
<div style=""></div>
<div class="content2">Information erstellt von:<br />Marco Walter, Simon Loferer, Nathalie Niekisch<br />e-fect eG</div>
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style='width:100%;background-color:#0061a1;'>
<div class='container'>
<div style="float:left;padding:30px 0 0 7px;"><a target="_blank" href="https://www.facebook.com/tink.bike"><img style="height:50px;" src="https://www2.tink-konstanz.de/img/footerFacebook.png" /></a></div>
<div style="float:left;padding:30px 0 0 20px;"><a href="http://tink.bike" target="_blank"><img style="height:50px;" src="https://www2.tink-konstanz.de/img/footerTink.png" /></a></div>
<div style="float:left;color:white;font-size:0.91em;padding:30px 15px 0 25px;width:330px;">TINK ist ein Angebot der Stadt Konstanz und ihrer Partner an alle Bürgerinnen und Bürger sowie Gäste der Stadt. TINK wird in den Pilotstädten Konstanz und Norderstedt gefördert vom Bundesministerium für Verkehr und digitale Infrastruktur (BMVI) im Rahmen des Nationalen Radverkehrsplans 2020 (NRVP).</div>
<div style="clear:both;float:left;padding:30px 0 0 7px;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer1_Bund.png" /></div>
<div style="float:left;padding:30px 0 0 0;"><img src="https://www2.tink-konstanz.de/img/footer2_fahrradspezialitaeten.png" style="height:105px;" /></div>
<div style="float:left;padding:30px 0 0 0;"><img src="https://www2.tink-konstanz.de/img/footer3_Konstanz.png" style="height:105px;" /></div>
<div style="float:left;padding:30px 0 0 0;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer3.1_Sponsoren.png" /></div>
<div style="float:left;padding:30px 0 0 0;"><img style="height:105px;" src="https://www2.tink-konstanz.de/img/footer4_ideelle_Partner.png" /></div>
<div style="clear:both;height:30px;width:100%;">&nbsp;</div>
</div>
</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,204 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK APP</title>
<base href="https://app.tink-konstanz.de/tinkapp/konrad-TINK-AGB" />
<meta name="author" content="Dominik Langer" />
<meta name="copyright" content="Dominik Langer" />
<meta name="description" content="Die TINK Konstanz Transporträder sind an ihren Stationen in den Stadtteilen Altstadt, Paradies und Petershausen aktuell mittels SMS anzumieten." />
<meta name="google-site-verification" content="_APrJWq--w-a4cD3sqOin3stmcxCvHpAVhV35E2sRnU" />
<meta name="keywords" content="TINK, Konstanz, Transportrad, Lastenrad, Leihrad, Mieten, fahrradspezialitäten" />
<meta name="publisher" content="Dominik Langer" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=yes" />
<link href="https://app2.tink-konstanz.de/img/nofavicon.ico" rel="shortcut icon" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="https://app2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://app2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://app2.tink-konstanz.de/img/OfficinaSansITCStd-Book.otf" media="screen" />
<link rel="stylesheet" type="text/css" href="https://app2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://app2.tink-konstanz.de/css/local_style.css");
</style>
<script src="https://app2.tink-konstanz.de/js/jquery-1.9.1.js" type="text/JAVASCRIPT"></script>
<script src="https://app2.tink-konstanz.de/jquery-ui/jquery-ui.min.js" type="text/JAVASCRIPT"></script>
<script src="https://app2.tink-konstanz.de/js/jquery.autosize.js" type="text/JAVASCRIPT"></script>
<script type="text/JAVASCRIPT"></script>
<script type="text/JAVASCRIPT"></script>
<script src="https://app2.tink-konstanz.de/js/konradspezial.js" type="text/JAVASCRIPT"></script>
<script src="https://app2.tink-konstanz.de/js/mobile_script.js" type="text/JAVASCRIPT"></script>
<script type="text/JAVASCRIPT">
//<![CDATA[
function onLoad() {
$('#no_javascript').hide();
//request_apijson('https://app.tink-konstanz.de');
}
//]]></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="onLoad();">
<style>
div#no_javascript {
display: all;
animation: opac 8s;
background-color: black;
width: 100%;
position: fixed;
z-index: 3000;
top: 1px;
padding: 10px;
color: white;
}
@keyframes opac {
from {
opacity: 0
}
to {
opacity: 1
}
}
</style>
<div id="no_javascript">Entschuldigung, leider verhindert Ihr Browser das Laden von Javascript. Die Applikation verwendet Techniken die ohne Javascript nicht funktionieren. Bitte überprüfen Sie die Javascript Einstellung.</div>
<div class='container'>
<div id='Contenttxt'>
<div class="content_title2" id="4967">Allgemeine Geschäftsbedingungen (AGB) für die Fahrradverleihsysteme konrad und TINK , betrieben durch Dominik Langer, fahrradspezialitaeten.com</div>
<div style=""></div>
<div class="content2">
Die vorliegenden Allgemeinen Geschäftsbedingungen (AGB) gelten für die Nutzung der Mietfahrräder konrad und TINK, welche durch Dominik Langer, fahrradspezialitaeten.com betrieben werden. Die Paragrafen 1 bis 8 regeln die Rechte und Pflichten im Rahmen der Benutzung und Ausleihe der Mietfahrräder. In den Paragrafen 9 bis 19 ist die Geschäftsbeziehung zwischen Dominik Langer als dem Betreiber der Fahrradverleihsysteme konrad und TINK sowie dem Kunden geklärt.<br /><br />
<span class='content12'>§ 1 Geltungsbereich der Allgemeinen Geschäftsbedingungen (AGB)</span><br /><br />
1) konrad und TINK (»Anbieter«) vermietet registrierten Kundinnen und Kunden (»Kunde«) Fahrräder bzw. Transportfahrräder (»Mietfahrräder«) soweit diese verfügbar sind.<br /><br />
2) Der Geltungsbereich der vorliegenden AGB bezieht sich auf konrad und TINK.<br /><br />
3) Ausleihe und Rückgabe sind per Smartphone-App, RFID-Chip, SMS und im internet (<a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a>), nach Eingabe des generierten Codes in den Bordcomputer möglich.<br /><br />
4) Durch die Ausleihe eines Fahrrads akzeptiert der Kunde die jeweils aktuelle Fassung der AGB.<br /><br />
<span class='content12'>§ 2 Anmeldung und Bestätigung</span><br /><br />
1) Die Anmeldung zur Registrierung (»Antrag«) ist im Internet, über die Smartphone-App oder persönlich bei fahrradspezialitaeten-konstanz, Schulthaiß Str. 1a, 78462 Konstanz möglich. Anmelden dürfen sich nur volljährige Personen.<br /><br />
2) Der Anbieter entscheidet über die Annahme des Antrags auf Abschluss einer Kundenbeziehung und ist im Rahmen des Antrags berechtigt, die Bonität des Antragsstellers durch den Zahlungspartner Payone prüfen zu lassen.<br /><br />
3) Im Verlauf der Registrierung legt der Antragsteller ein persönliches Passwort fest. In Kombination mit seiner E-Mail Adresse, kann sich der Antragsteller in der Smartphone App sowie in sein Online-Kundenkonto einloggen oder Buchungen per SMS beantragen.<br /><br />
4) Die Mitteilung der Freischaltung bedeutet die Annahme des Antrags. Die Mitteilung kann mündlich, schriftlich, telefonisch, per E-Mail oder per SMS erfolgen.<br /><br />
5) Mit erfolgreicher Registrierung kann der Kunde alle Mietfahrräder von konrad bzw. TINK mieten. Eine Übersicht über die einzelnen Standorte finden Sie auf <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a>.<br /><br />
6) Die Registrierung ist kostenfrei, dennoch muss für den Fall von kostenpflichtigen Fahrten vor Fahrtantritt ein gültiges Zahlungsmittel hinterlegt werden. Je nach Tarifwahl ist der Anbieter berechtigt, regelmäßig Mietgebühren zu erheben. Die Höhe dieser Gebühren ist telefonisch zu erfragen bzw. der aktuellen Preisliste zu entnehmen.<br /><br />
7) Der Kunde verpflichtet sich, den Anbieter während der Geschäftsbeziehung unverzüglich über eintretende Änderungen seiner persönlichen Daten, sowie der für die Abrechnung relevanten Daten (Bank- bzw. Kreditkartendaten) zu informieren.<br /><br />
<span class='content12'>§ 3 Nutzungsvorschriften</span><br /><br />
1) Die Mietfahrräder dürfen nicht benutzt werden:<br /><br />
a) von Personen, die das 18. Lebensjahr noch nicht vollendet haben, mit Ausnahme in Begleitung eines Volljährigen;<br /><br />
b) für den Transport einer zusätzlichen Person;<br /><br />
c) für Fahrten in die Schweiz (dies gilt nur für Schweizer Bürger und begründet sich durch das Zollrecht);<br /><br />
d) um an Fahrradrennen oder Fahrradtests teilzunehmen, es sei denn, der Anbieter hat dafür eine schriftliche Genehmigung erteilt;<br /><br />
e) zur Weitervermietung;<br /><br />
f) bei starkem Wind oder stürmischem Wetter;<br /><br />
g) wenn der Fahrer unter dem Einfluss von Alkohol oder Drogen steht.<br /><br />
2) Der Kunde verpflichtet sich, die Regeln der geltenden <br />Straßenverkehrsordnung (StVO) zu beachten.<br /><br />
3) Das Freihändigfahren ist zu keiner Zeit gestattet.<br /><br />
4) Der Kunde verpflichtet sich für die ordnungsgemäße Sicherung der Gegenstände, die er transportiert, Sorge zu tragen. Weiterhin hat sich der Kunde beim Transport von Gegenständen von deren ordnungsgemäßer Befestigung zu überzeugen.<br /><br />
5) Das Gesamtgewicht des Mietfahrrads darf inklusive Gepäck und Nutzer 150kg nicht überschreiten.<br /><br />
6) Am Mietrad dürfen keine Eingriffe oder Umbauten vorgenommen werden.<br /><br />
7) Der Anbieter hat das Recht, die Nutzerdaten des Kunden zu sperren und ihn von der weiteren Benutzung der Mietfahrräder auszuschließen, wenn sich der Kunde nicht an die sachgemäße Nutzung hält.<br /><br />
8) Ist das Mietfahrrad zurückgegeben worden und ist beim Kunden eine Benachrichtigung über die Rückgabe des Mietfahrrades eingegangen, so darf er das Mietfahrrad nicht mehr nutzen. Es sei denn, er mietet das Mietfahrrad erneut an. <br /><br />
<span class='content12'>§ 4 Ausleihlimit</span><br /><br />
1) Ein registrierter Kunde darf maximal 3 Mietfahrräder gleichzeitig ausleihen.<br /><br />
2) Abweichende Vereinbarungen sind möglich und im Einzelfall, abhängig von der Verfügbarkeit, mit dem Anbieter zu treffen.<br /><br />
<span class='content12'>§ 5 Dauer des Mietverhältnisses</span><br /><br />
1) Die kostenpflichtige Anmietung eines Mietfahrrades beginnt mit der Eingabe des Codes in den Bordcomputer oder mit der Entsperrung mittels RFID Chip.<br /><br />
2) Der Kunde beendet die Anmietung über die entsprechende Funktion am Bordcomputer.<br /><br />
<span class='content12'>§ 6 Zustand des Mietfahrrades</span><br /><br />
1) Vor der Nutzung muss sich der Kunde mit der Funktionsweise des Mietfahrrades vertraut machen. Siehe <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a>.<br /><br />
2) Der Kunde verpflichtet sich, das Mietfahrrad vor dem Fahrtantritt auf Mängel, Verkehrssicherheit und Funktionstüchtigkeit zu prüfen. Insbesondere gilt dies für die Funktion der Lichtanlage und der Bremsen, den Druck der Reifen, den ordnungsgemäßen Zustand von Sattel, Lenker und Rahmen, sowie das Festsitzen aller sicherheitsrelevanten Schrauben.<br /><br />
3) Bei einem technischen Mangel, der die Verkehrssicherheit beeinträchtigen könnte, ist von der Nutzung abzusehen. Tritt ein solcher Zustand während des Mietverhältnisses ein, ist die Nutzung des Mietfahrrades sofort zu beenden. In beiden Fällen ist der Anbieter unverzüglich zu informieren. Dies gilt auch für Mängel an Reifen, Felgen oder Gangschaltung.<br />Diese müssen dem Anbieter über die Servicehotline oder per E-Mail angezeigt werden.<br /><br />
<span class='content12'>§ 7 Abstellen und Parken des Mietfahrrades</span><br /><br />
1) Das Mietfahrrad ist gut sichtbar abzustellen. Dabei muss der Kunde beim Parken und Abstellen dafür Sorge tragen, dass die Regeln der Straßenverkehrsordnung (StVO) eingehalten werden, die Verkehrssicherheit nicht beeinträchtigt wird, Fahrzeuge und andere Gegenstände nicht beschädigt werden können und andere Verkehrsteilnehmer nicht behindert werden. In jedem Fall ist zum Abstellen der integrierte Ständer des Mietfahrrades zu verwenden bzw. bei Dreirädern die Feststellbremse zu betätigen.<br /><br />
2) Das Mietfahrrad darf insbesondere nicht geparkt oder abgestellt werden:<br /><br />
a) an Verkehrsampeln,<br /><br />
b) an Parkscheinautomaten oder Parkuhren,<br /><br />
c) an Straßenschildern,<br /><br />
d) auf Gehwegen, wenn dadurch eine Durchgangsbreite von 1,50m unterschritten wird,<br /><br />
e) vor, an und auf Rettungswegen und Feuerwehranfahrtszonen,<br /><br />
f) wenn dadurch die stationäre Werbung eines Dritten verdeckt wird.<br /><br />
3) Das Mietfahrrad muss immer abgeschlossen werden, auch wenn der Kunde es nur vorübergehend parkt.<br /><br />
4) Bei Zuwiderhandlung werden Servicegebühren fällig (siehe §8). Darüber hinaus stellt der Anbieter dem Kunden die ggf. anfallenden behördlichen Gebühren oder Bussgelder in Rechnung.<br /><br />
5) Dem Kunden ist es untersagt, die Mietfahrräder vorübergehend oder dauerhaft in Gebäuden, Hinterhöfen oder in Fahrzeugen abzustellen.<br /><br />
<span class='content12'>§ 8 Rückgabevorschriften</span><br /><br />
1) Außerhalb der Mietfahrrad-Stationen ist die Rückgabe der Mietfahrräder nicht zulässig.<br /><br />
2) Bei Zuwiderhandlung werden für die Rückführung Servicegebühren erhoben. Diese belaufen sich innerhalb der Grenzen der Stadt Konstanz auf 15€. Ausserhalb der Stadtgrenze addiert sich dazu ab Stadtgrenze pro Kilometer 2€.<br /><br />
3) Zur Rückgabe muss das Fahrrad an den im Internet bzw. in der Smartphone-App veröffentlichten Stationen mithilfe des Steckseils an der Station angeschlossen werden.<br /><br />
4) Ist eine Station voll besetzt muss eine andere Station mit freien Parkplätzen angefahren werden.<br /><br />
4) Der Kunde ist wegen möglicher Rückfragen verpflichtet, den Abstellort bis mindestens 48 Stunden nach Beendigung des Mietverhältnisses benennen zu können.<br /><br />
<span class='content12'>§ 9 Haftung Anbieter und Haftung des Kunden</span><br /><br />
1) Der Kunde nutzt die Serviceleistungen des Anbieters auf eigenes Risiko. Die von ihm verursachten Schäden hat der Kunde zu verantworten und eigenverantwortlich abzusichern. Regressansprüche des Haftpflichtversicherers des Anbieters gegenüber dem Kunden bleiben davon unberührt.<br /><br />
2) Der Kunde haftet für Schäden, die bis 48 Stunden nach der Rückgabe entstehen, längstens aber bis der Anbieter das zurückgegebene Mietfahrrad kontrolliert hat oder es neu vermietet wurde. Der Kunde haftet für Schäden aus Diebstahl oder Beschädigung des Mietfahrrades entsprechend den anfallenden Material- und Arbeitskosten bis zu einem Höchstbetrag von 75 €. Diese Haftungsbegrenzung gilt allerdings nicht, wenn der Kunde die Schäden vorsätzlich oder grob fahrlässig herbeigeführt und somit selbst zu verantworten hat. In diesem Fall orientiert sich der Haftungsbetrag am Schadenswert.<br />Der Anbieter informiert den Kunden bei Vorliegen eines Schadens umgehend; der Anbieter ist in der Beweispflicht. Für Schäden, die dem Kunden nicht innerhalb von 48 Stunden nach Ablauf der Mietzeit angezeigt werden, haftet der Kunde nicht.<br /><br />
3) Für alle Schäden und Kosten, die dem Anbieter aus einer Zuwiderhandlung gegen die aufgeführten Mitteilungs- und Mitwirkungspflichten entstehen, haftet der Kunde.<br /><br />
4) Der Anbieter haftet gegenüber dem Kunden für Vorsatz und grobe Fahrlässigkeit. Für sonstige schuldhafte Verletzungen von wesentlichen Vertragspflichten (Kardinalpflichten) haftet der Anbieter, gleich welchen Rechtsgrundes, nur für vertragstypische, d. h. vorhersehbare Schäden. Der Anbieter haftet nicht für Schäden an den mit dem Mietfahrrad transportierten Gegenständen. Im Übrigen ist die Haftung des Anbieters ausgeschlossen.<br /><br />
5) Eine Haftung des Anbieters entfällt im Falle unbefugter und/oder unerlaubter Benutzung des Mietfahrrades.<br /><br />
6) Den Diebstahl eines Mietfahrrades während der Mietzeit hat der Kunde unverzüglich dem Anbieter und einer zuständigen Polizeidienststelle unter Bekanntgabe der Radnummer anzuzeigen. Das polizeiliche Aktenzeichen ist dem Anbieter unverzüglich bekannt zu geben.<br /><br />
<span class='content12'>§ 10 Verhalten bei Unfall</span><br /><br />
Dem Anbieter sind Unfälle unverzüglich zu melden. Sind neben dem Mieter noch andere Personen oder das Eigentum Dritter betroffen, hat der Kunde unverzüglich die Polizei zu verständigen. Im Falle einer Missachtung dieser Mitteilungspflicht haftet der Kunde für hieraus resultierende Schäden und Kosten.<br /><br />
<span class='content12'>§ 11 Nutzung der Kundenkarte, eines E-Tickets oder eines elektronischen Mitarbeiterausweises</span><br /><br />
1) Nutzt der Kunde als Zugangsmedium einen vom Anbieter oder einem Kooperationspartner ausgegebenen RFID-Chip, so erklärt er sich mit der erstmaligen Nutzung dieses Chips bereit, dass der Anbieter für die Geschäftsprozesse erforderliche Daten beim Kooperationspartner anfordern darf.<br /><br />
2) Der Kunde kann beim Anbieter einen RFID-Chip gegen 5€ Schutzgebühr bestellen, direkt bei fahrradspezialitaeten-konstanz, Schulthaißstr. 1A, 78462 Konstanz oder im Energiewürfel der SWK, Max-Stromeyer-Straße 21a abholen. Dieser Chip dient als Zugangsmedium am Bordcomputer.<br /><br />
3) Der RFID-Chip ist nicht auf andere Personen übertragbar.<br /><br />
4) Geht der RFID-Chip verloren, so muss der Kunde diesen über die Servicehotline sperren lassen. Mißbrauch des RFID-Chips hat der Kunde zu verantworten. Ein Ersatz kostete 5€.<br /><br />
<span class='content12'>§ 12 Vertraulichkeit der persönlichen Nutzerdaten</span><br /><br />
1) Der Kunde verpflichtet sich, seine persönlichen Nutzerdaten, dies gilt insbesondere für sein persönliches Passwort, vor dem unbefugten Zugriff durch Dritte zu schützen.<br /><br />
2) Der Anbieter weist ausdrücklich darauf hin, dass keiner seiner Mitarbeiter, berechtigt ist, das Passwort abzufragen.<br /><br />
3) Der Kunde darf jederzeit und beliebig oft seine Nutzerdaten ändern.<br /><br />
4) Der Kunde muss den den Anbieter informieren, sobald ihm Anhaltspunkte bekannt werden, die darauf schließen lassen, dass seine Nutzerdaten missbräuchlich verwendet werden.<br /><br />
5) Der Kunde kann sein Kundenkonto im Internet auf <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a> oder durch schriftliche Mitteilung an den Anbieter kündigen.<br /><br />
<span class='content12'>§ 13 Benutzung der Mietfahrräder mit Nutzerdaten und Sperrung</span><br /><br />
1) Aus begründetem Anlass (insbesondere im Falle des Missbrauchs von Nutzerdaten) kann der Anbieter Kunden von der Mietfahrrad-Nutzung ausschließen.<br /><br />
2) Die Haftungsbegrenzung gilt nicht, falls der Kunde die missbräuchliche Nutzung seiner persönlichen Nutzerdaten vorsätzlich oder grob fahrlässig zugelassen hat (s. §9 Abs. 2).<br /><br />
<span class='content12'>§ 14 Preise</span><br /><br />
Es gelten die jeweils aktuellen Preise, die im Internet auf <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a> veröffentlicht sind.<br /><br />
<span class='content12'>§ 15 Zahlung und Zahlungsverzug</span><br /><br />
1) Der Kunde verpflichtet sich zur Zahlung der Nutzungsentgelte per Kreditkarte oder durch Überweisung in Verbindung mit der Teilnahme am Einzugsermächtigungsverfahren (Lastschriftverfahren). Für Kunden mit einer Bankverbindung außerhalb Deutschland ist nur die Zahlung per Kreditkarte möglich. Es ist dem Nutzer jederzeit möglich, das in seinem Kundenkonto hinterlegte Zahlungsmittel zu wechseln.<br /><br />
2) Sollte eine Lastschrift mangels Deckung oder aus anderen vom Kunden zu vertretenden Gründen nicht eingelöst werden, stellt der Anbieter den hierdurch entstehenden Mehraufwand bis zur Höhe des tatsächlich entstandenen Aufwandes in Rechnung (mindestens 10€ pro Vorgang), es sei denn, der Kunde kann einen geringeren Schaden nachweisen.<br /><br />
3) Befindet sich der Kunde mit der Zahlungen in Verzug, werden vorbehaltlich der Geltendmachung eines weiteren Verzugsschadens Zinsen in Höhe von 5 von 100 zuzüglich dem gültigen Basiszinssatz fällig. Zusätzlich werden Mahngebühren gemäß dem angefallenen Aufwand fällig. Ferner ist der Anbieter berechtigt, alle weiteren offenen Forderungen gegenüber dem Kunden sofort fällig zu stellen und die vertraglichen Leistungen einzustellen, bis der Kunde allen insgesamt fälligen Verpflichtungen nachgekommen ist.<br /><br />
<span class='content12'>§ 16 Abrechnung, Fahrtenaufstellung und Prüfung</span><br /><br />
1) Der Anbieter stellt dem Kunden Entgelte gemäß der gültigen Preisliste (§14) in Rechnung. Die beendeten Nutzungsvorgänge einschließlich Kosten- und Zeitangabe sind im Kundenkonto auf <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a> für den Kunden einsehbar. Außerordentlich berechnete Vorgänge, welche nicht automatisch erfasst werden können (z. B. durch nicht vertragsgerechte Nutzung anfallende Gebühren oder Servicegebühren), sind darin nicht enthalten.<br /><br />
2) Die Abbuchung erfolgt grundsätzlich automatisch. Der Anbieter behält sich vor, Kunden zur Begleichung von offenen Beträgen schriftlich oder telefonisch aufzufordern.<br /><br />
3) Einwendungen gegen Belastungen zugunsten des Anbieters sind innerhalb von 14 Tagen nach Erhalt der Rechnung schriftlich geltend zu machen. Ansprüche des Kunden nach Fristablauf, auch bei begründeten Einwendungen, bleiben unberührt. Rückzahlungsansprüche des Kunden werden seinem Kundenkonto gutgeschrieben und mit der nächsten fälligen Forderung verrechnet, sofern der Kunde keine andere Weisung erteilt.<br /><br />
4) Forderungen des Anbieters kann der Kunde nur mit unbestrittenen oder rechtskräftig festgestellten Forderungen aufrechnen.<br /><br />
<span class='content12'>§ 17 Kündigung und Löschung von Kundendaten</span><br /><br />
1) Beide Vertragsparteien können das Vertragsverhältnis jederzeit ordentlich kündigen. Das Recht zur außerordentlichen Kündigung bleibt unberührt. Der Kunde kann sein Kundenkonto im Internet auf <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a> oder durch schriftliche Mitteilung kündigen. Die schriftliche Kündigung ist zu richten an: fahrradspezialitaeten.com, Marie-Curie-Str. 1, 79100 Freiburg oder per E-Mail an: konrad@fahrradspezialitaeten.com.<br /><br />
2) Sondertarife sind an bestimmte Laufzeiten gebunden. Die Kündigungsbedingungen von Sondertarifen sind in §14 Abs. 1 c und 2 c spezifiziert. <br /><br />
<span class='content12'>§ 18 Datenschutz</span><br /><br />
1) Der Kunde erklärt sich einverstanden, dass der Anbieter seine persönlichen Daten speichert. Der Anbieter verpflichtet sich im Gegenzug dazu, diese ausschließlich im Einklang mit den Bestimmungen des Bundesdatenschutzgesetzes zu verwenden.<br /><br />
2) Im Falle eines Ordnungswidrigkeits- oder Strafverfahrens ist der Anbieter berechtigt in erforderlichem Umfang Informationen über den Kunden, insbesondere die Anschrift, an Behörden weiterzugeben.<br /><br />
3) Bei der Zahlungsart Kreditkarte werden die kundenspezifischen Daten an den Zahlungsdienstleister Payone ( eine Unternehmen der Sparkasse Finanzgruppe) zur Verifizierung und weiteren Abrechnung der Ausleihgebühren weitergegeben. Nach der Registrierung sind die Kreditkartendaten für den Anbieter nicht mehr einsehbar.<br /><br />
4) Weitere Informationen zur personenbezogenen Datennutzung und -verarbeitung erhalten Sie in unseren Datenschutzbestimmungen, siehe <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a>.<br /><br />
<span class='content12'>§ 19 Sonstiges</span><br /><br />
1) Es gilt deutsches Recht. Gerichtsstand für alle Streitigkeiten, die aus der Inanspruchnahme der Leistungen des Anbieters sowie der Nutzung von <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a> oder Streitigkeiten, die damit in Zusammenhang stehen, ist Freiburg im Breisgau. Dies gilt sofern der Kunde keinen allgemeinen Gerichtsstand im Inland hat oder er nach Vertragsabschluss seinen Wohnsitz oder seinen gewöhnlichen Aufenthalt ins Ausland verlegt oder sein Wohnsitz oder sein gewöhnlicher Aufenthalt zum Zeitpunkt der Klageerhebung nicht bekannt ist oder wenn der Kunde Vollkaufmann oder eine juristische Person des öffentlichen Rechts oder ein öffentliches Sondervermögen ist.<br /><br />
2) Mündliche Nebenabsprachen bestehen nicht.<br /><br />
3) Sollte eine Bestimmung der AGB unwirksam sein oder werden, so wird dadurch die Wirksamkeit der übrigen Bestimmungen nicht berührt. An Stelle der unwirksamen Bestimmung tritt eine rechtlich zulässige, die Sinn und Zweck der unwirksamen Bestimmung so nahe wie möglich kommt.<br /><br />
<br />Servicehotline: +49 761/45370099 (kostenpflichtiger Anruf ins deutsche Festnetz)<br />E-Mail: konrad@fahrradspezialitaeten.com<br />Internet: <a href="http://www.konrad-konstanz.de/">www.konrad-konstanz.de</a><br /><br />
<br />AGB | Stand: 23.09.2018
</div>
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<style>
.ui-dialog .ui-dialog-content {
background: white;
}
.ui-dialog > .ui-widget-header {
color: white;
font-weight: normal;
border: 1px solid #0061a1;
background: #0061a1;
}
.ui-widget-overlay {
background: #666 url("https://app2.tink-konstanz.de/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png") 50% 50% repeat;
opacity: .5;
filter: Alpha(Opacity=50);
}
</style>
</div>
</div>
<script src='https://app2.tink-konstanz.de/bootstrap-3.3.6-dist/js/bootstrap.min.js'></script>
</body>
</html>

View file

@ -0,0 +1,213 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK APP</title>
<base href="https://app.tink-konstanz.de/tinkapp/Datenschutz" />
<meta name="author" content="Dominik Langer" />
<meta name="copyright" content="Dominik Langer" />
<meta name="description" content="Die TINK Konstanz Transporträder sind an ihren Stationen in den Stadtteilen Altstadt, Paradies und Petershausen aktuell mittels SMS anzumieten." />
<meta name="google-site-verification" content="_APrJWq--w-a4cD3sqOin3stmcxCvHpAVhV35E2sRnU" />
<meta name="keywords" content="TINK, Konstanz, Transportrad, Lastenrad, Leihrad, Mieten, fahrradspezialitäten" />
<meta name="publisher" content="Dominik Langer" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=yes" />
<link href="https://app2.tink-konstanz.de/img/nofavicon.ico" rel="shortcut icon" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="https://app2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://app2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://app2.tink-konstanz.de/img/OfficinaSansITCStd-Book.otf" media="screen" />
<link rel="stylesheet" type="text/css" href="https://app2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://app2.tink-konstanz.de/css/local_style.css");
</style>
<script src="https://app2.tink-konstanz.de/js/jquery-1.9.1.js" type="text/JAVASCRIPT"></script>
<script src="https://app2.tink-konstanz.de/jquery-ui/jquery-ui.min.js" type="text/JAVASCRIPT"></script>
<script src="https://app2.tink-konstanz.de/js/jquery.autosize.js" type="text/JAVASCRIPT"></script>
<script type="text/JAVASCRIPT"></script>
<script type="text/JAVASCRIPT"></script>
<script src="https://app2.tink-konstanz.de/js/konradspezial.js" type="text/JAVASCRIPT"></script>
<script src="https://app2.tink-konstanz.de/js/mobile_script.js" type="text/JAVASCRIPT"></script>
<script type="text/JAVASCRIPT">
//<![CDATA[
function onLoad() {
$('#no_javascript').hide();
//request_apijson('https://app.tink-konstanz.de');
}
//]]></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="onLoad();">
<style>
div#no_javascript {
display: all;
animation: opac 8s;
background-color: black;
width: 100%;
position: fixed;
z-index: 3000;
top: 1px;
padding: 10px;
color: white;
}
@keyframes opac {
from {
opacity: 0
}
to {
opacity: 1
}
}
</style>
<div id="no_javascript">Entschuldigung, leider verhindert Ihr Browser das Laden von Javascript. Die Applikation verwendet Techniken die ohne Javascript nicht funktionieren. Bitte überprüfen Sie die Javascript Einstellung.</div>
<div class='container'>
<div id='Contenttxt'>
<div class="content_title2" id="4958">Datenschutzerklärung</div>
<div style=""></div>
<div class="content2">
<span class='content_title2'>Gliederung Datenschutzbedingungen</span><br /><br />
Anwendungszweck der TINK-App ist die Nutzung der Fahrrad Mietsysteme TINK und Konrad. Diese Mietsysteme werden durch die Stadt Konstanz und ihre Partner betrieben und erlauben, durch einen über das Internet erreichbaren Rechner (TINK/ Konrad-Server), die Kommunikation der TINK-App mit dem TINK- und Konrad Fahrradmietsystem. Für die mit der TINK-App erfassten Nutzerdaten gelten daher auch die Datenschutzbedingungen des TINK/ Konrad Mietsystems. Diese Datenschutzbedingungen finden sich unten im Anschluss an die Datenschutzbedingungen der TINK-App.<br /><br />
<span class='content_title2'>I. Datenschutzbedingungen TINK-App</span><br /><br />
Der TINK-App Entwickler gewährleistet, dass die anfallenden Nutzerdaten lediglich im Zusammenhang mit der Verarbeitung der Nutzeranfragen und zu internen Zwecken erhoben, bearbeitet und gespeichert werden.<br /><br />
<span class='content1'>Datenübermittlung an Dritte</span><br /><br />
Es findet keine Datenübermittlung an Dritte ohne Einwilligung des Betroffenen oder gesetzliche Grundlage statt. Hiervon ausgenommen ist die Datenübermittlung an den TINK /Konrad-Server, die zwingend notwendig ist, um die Mietsysteme zu nutzen.<br /><br />
<span class='content1'>Erteilte Berechtigungen</span><br /><br />
1. Voller Netzwerkzugriff und Netzwerkverbindungen anzeigen<br />
Wird benötigt für die Kommunikation mit dem TINK/ Konrad Server, da diese Rechner die Verwaltung der Mieträder zentral für alle Anwender übernehmen.<br />
2. SD- Karteninhalt ändern/ löschen und SD- Karteninhalte lesen<br />
Für den Fall, dass in der App unerwartet Fehler auftreten, wird ein Protokoll erstellt und auf SD- Karte abgelegt. Dieses Protokoll kann vom Benutzer bei Bedarf als E-Mail- Anhang an den TINK- Service zur Fehleranalyse versendet werden.<br />
3. Zugriff auf Bluetooth<br />
Steuerung Bluetooth-Schloss.
4. Zugriff auf Ortsinformationen und Bluetooth<br />
Steuerung Bluetooth-Schloss (Android).<br />
Abfrage Standortinformation bei Anzeige von aktivem Kartenausschnitt.<br />
Abfrage Standortinformation bei Rückgabe von Rädern.<br />
<br />
<span class='content1'>E-Mail Sicherheit</span><br /><br />
Der Nutzer ist mit elektronischer Kommunikation einverstanden, sobald er selbst den elektronischen Kontakt zur TINK- Konstanz oder zum Entwickler der App eröffnet. Der Nutzer wird darauf hingewiesen, dass E- Mails auf dem Übertragungsweg unbefugt und unbemerkt mitgelesen oder verändert werden können. TINK- Konstanz sowie der TINK-App Entwickler verwenden eine Software zur Filterung von unerwünschten E-Mails (Spam- Filter). Durch den Spam- Filter können E- Mails abgewiesen werden, wenn diese durch bestimmte Merkmale fälschlich als Spam identifiziert wurden.<br /><br />
<span class='content1'>Datenübertragung</span><br /><br />
Die Kommunikation mit dem TINK/ Konrad-Server erfolgt ausschließlich verschlüsselt.<br /><br />
<span class='content1'>Widerspruchsrecht des Nutzers</span><br /><br />
Soweit der Nutzer eine aktive Datennutzung für interne Zwecke durch TINK-App nicht möchte, kann die TINK-App deinstalliert werden, um dies zu erreichen.<br /><br />
Stand Datenschutzerklärung TINK-App: 2018-06-09.<br /><br />
<br /><span class='content_title2'>II. Datenschutzbedingungen Mietsysteme TINK und Konrad</span><br /><br />
<span class='content_title2'>1. Datenschutz auf einen Blick</span><br /><br />
<span class='content13'>Allgemeine Hinweise</span><br /><br />
Die folgenden Hinweise geben einen einfachen Überblick darüber, was mit Ihren personenbezogenen Daten passiert, wenn Sie unsere Website besuchen. Personenbezogene Daten sind alle Daten, mit denen Sie persönlich identifiziert werden können. Ausführliche Informationen zum Thema Datenschutz entnehmen Sie unserer unter diesem Text aufgeführten Datenschutzerklärung.<br /><br />
<span class='content1'>Datenerfassung auf unserer Website</span><br /><br />
<span class='content13'>Wer ist verantwortlich für die Datenerfassung auf dieser Website?</span><br /><br />
Die Datenverarbeitung auf dieser Website erfolgt durch den Websitebetreiber. Dessen Kontaktdaten können Sie dem Impressum dieser Website entnehmen.<br /><br />
<span class='content13'>Wie erfassen wir Ihre Daten?</span><br /><br />
Ihre Daten werden zum einen dadurch erhoben, dass Sie uns diese mitteilen. Hierbei kann es sich z.B. um Daten handeln, die Sie in ein Kontaktformular eingeben.<br /><br />
Andere Daten werden automatisch beim Besuch der Website durch unsere IT-Systeme erfasst. Das sind vor allem technische Daten (z.B. Internetbrowser, Betriebssystem oder Uhrzeit des Seitenaufrufs). Die Erfassung dieser Daten erfolgt automatisch, sobald Sie unsere Website betreten.<br /><br />
<span class='content13'>Wofür nutzen wir Ihre Daten?</span><br /><br />
Ein Teil der Daten wird erhoben, um eine fehlerfreie Bereitstellung der Website zu gewährleisten. Andere Daten können zur Analyse Ihres Nutzerverhaltens verwendet werden.<br /><br />
<span class='content13'>Welche Rechte haben Sie bezüglich Ihrer Daten?</span><br /><br />
Sie haben jederzeit das Recht unentgeltlich Auskunft über Herkunft, Empfänger und Zweck Ihrer gespeicherten personenbezogenen Daten zu erhalten. Sie haben außerdem ein Recht, die Berichtigung, Sperrung oder Löschung dieser Daten zu verlangen. Hierzu sowie zu weiteren Fragen zum Thema Datenschutz können Sie sich jederzeit unter der im Impressum angegebenen Adresse an uns wenden. Des Weiteren steht Ihnen ein Beschwerderecht bei der zuständigen Aufsichtsbehörde zu.<br /><br />
<span class='content1'>Analyse-Tools und Tools von Drittanbietern</span><br /><br />
Beim Besuch unserer Website kann Ihr Surf-Verhalten statistisch ausgewertet werden. Das geschieht vor allem mit Cookies und mit sogenannten Analyseprogrammen. Die Analyse Ihres Surf-Verhaltens erfolgt in der Regel anonym; das Surf-Verhalten kann nicht zu Ihnen zurückverfolgt werden. Sie können dieser Analyse widersprechen oder sie durch die Nichtbenutzung bestimmter Tools verhindern. Detaillierte Informationen dazu finden Sie in der folgenden Datenschutzerklärung.<br /><br />
Sie können dieser Analyse widersprechen. Über die Widerspruchsmöglichkeiten werden wir Sie in dieser Datenschutzerklärung informieren.<br /><br />
<span class='content_title2'>2. Allgemeine Hinweise und Pflichtinformationen</span><br /><br />
<span class='content1'>Datenschutz</span><br /><br />
Die Betreiber dieser Seiten nehmen den Schutz Ihrer persönlichen Daten sehr ernst. Wir behandeln Ihre personenbezogenen Daten vertraulich und entsprechend der gesetzlichen Datenschutzvorschriften sowie dieser Datenschutzerklärung.<br /><br />
Wenn Sie diese Website benutzen, werden verschiedene personenbezogene Daten erhoben. Personenbezogene Daten sind Daten, mit denen Sie persönlich identifiziert werden können. Die vorliegende Datenschutzerklärung erläutert, welche Daten wir erheben und wofür wir sie nutzen. Sie erläutert auch, wie und zu welchem Zweck das geschieht.<br /><br />
Wir weisen darauf hin, dass die Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen kann. Ein lückenloser Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich.<br /><br />
<span class='content1'>Hinweis zur verantwortlichen Stelle</span><br /><br />
Die verantwortliche Stelle für die Datenverarbeitung auf dieser Website ist:<br /><br />
Dominik Langer<br />Fahrradspezialitäten<br />Marie-Curie-Str.1<br />79100 Freiburg<br /><br />
Tel.: 07531-3694389<br />eMail: tink@fahrradspezialitaeten.com<br /><br />
Verantwortliche Stelle ist die natürliche oder juristische Person, die allein oder gemeinsam mit anderen über die Zwecke und Mittel der Verarbeitung von personenbezogenen Daten (z.B. Namen, E-Mail-Adressen o. Ä.) entscheidet.<br /><br />
<span class='content1'>Widerruf Ihrer Einwilligung zur Datenverarbeitung</span><br /><br />
Viele Datenverarbeitungsvorgänge sind nur mit Ihrer ausdrücklichen Einwilligung möglich. Sie können eine bereits erteilte Einwilligung jederzeit widerrufen. Dazu reicht eine formlose Mitteilung per E-Mail an uns. Die Rechtmäßigkeit der bis zum Widerruf erfolgten Datenverarbeitung bleibt vom Widerruf unberührt.<br /><br />
<span class='content1'>Beschwerderecht bei der zuständigen Aufsichtsbehörde</span><br /><br />
Im Falle datenschutzrechtlicher Verstöße steht dem Betroffenen ein Beschwerderecht bei der zuständigen Aufsichtsbehörde zu. Zuständige Aufsichtsbehörde in datenschutzrechtlichen Fragen ist der Landesdatenschutzbeauftragte des Bundeslandes, in dem unser Unternehmen seinen Sitz hat. Eine Liste der Datenschutzbeauftragten sowie deren Kontaktdaten können folgendem Link entnommen werden: https://www.bfdi.bund.de/DE/Infothek/Anschriften_Links/anschriften_links-node.html.<br /><br />
<span class='content1'>Recht auf Datenübertragbarkeit</span><br /><br />
Sie haben das Recht, Daten, die wir auf Grundlage Ihrer Einwilligung oder in Erfüllung eines Vertrags automatisiert verarbeiten, an sich oder an einen Dritten in einem gängigen, maschinenlesbaren Format aushändigen zu lassen. Sofern Sie die direkte Übertragung der Daten an einen anderen Verantwortlichen verlangen, erfolgt dies nur, soweit es technisch machbar ist.<br /><br />
<span class='content1'>SSL- bzw. TLS-Verschlüsselung</span><br /><br />
Diese Seite nutzt aus Sicherheitsgründen und zum Schutz der Übertragung vertraulicher Inhalte, wie zum Beispiel Bestellungen oder Anfragen, die Sie an uns als Seitenbetreiber senden, eine SSL-bzw. TLS-Verschlüsselung. Eine verschlüsselte Verbindung erkennen Sie daran, dass die Adresszeile des Browsers von “http://” auf “https://” wechselt und an dem Schloss-Symbol in Ihrer Browserzeile.<br /><br />
Wenn die SSL- bzw. TLS-Verschlüsselung aktiviert ist, können die Daten, die Sie an uns übermitteln, nicht von Dritten mitgelesen werden.<br /><br />
<span class='content1'>Verschlüsselter Zahlungsverkehr auf dieser Website</span><br /><br />
Besteht nach dem Abschluss eines kostenpflichtigen Vertrags eine Verpflichtung, uns Ihre Zahlungsdaten (z.B. Kontonummer bei Einzugsermächtigung) zu übermitteln, werden diese Daten zur Zahlungsabwicklung benötigt.<br /><br />
Der Zahlungsverkehr über die gängigen Zahlungsmittel (Visa/MasterCard, Lastschriftverfahren) erfolgt ausschließlich über eine verschlüsselte SSL- bzw. TLS-Verbindung. Eine verschlüsselte Verbindung erkennen Sie daran, dass die Adresszeile des Browsers von "http://" auf "https://" wechselt und an dem <br />Schloss-Symbol in Ihrer Browserzeile.<br /><br />
Bei verschlüsselter Kommunikation können Ihre Zahlungsdaten, die Sie an uns übermitteln, nicht von Dritten mitgelesen werden.<br /><br />
<span class='content1'>Auskunft, Sperrung, Löschung</span><br /><br />
Sie haben im Rahmen der geltenden gesetzlichen Bestimmungen jederzeit das Recht auf unentgeltliche Auskunft über Ihre gespeicherten personenbezogenen Daten, deren Herkunft und Empfänger und den Zweck der Datenverarbeitung und ggf. ein Recht auf Berichtigung, Sperrung oder Löschung dieser Daten. Hierzu sowie zu weiteren Fragen zum Thema personenbezogene Daten können Sie sich jederzeit unter der im Impressum angegebenen Adresse an uns wenden.<br /><br />
<span class='content1'>Widerspruch gegen Werbe-Mails</span><br /><br />
Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit widersprochen. Die Betreiber der Seiten behalten sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-E-Mails, vor.<br /><br />
<span class='content_title2'>3. Datenerfassung auf unserer Website</span><br /><br />
<span class='content1'>Cookies</span><br /><br />
Die Internetseiten verwenden teilweise so genannte Cookies. Cookies richten auf Ihrem Rechner keinen Schaden an und enthalten keine Viren. Cookies dienen dazu, unser Angebot nutzerfreundlicher, effektiver und sicherer zu machen. Cookies sind kleine Textdateien, die auf Ihrem Rechner abgelegt werden und die Ihr Browser speichert.<br /><br />
Die meisten der von uns verwendeten Cookies sind so genannte “Session-Cookies”. Sie werden nach Ende Ihres Besuchs automatisch gelöscht. Andere Cookies bleiben auf Ihrem Endgerät gespeichert bis Sie diese löschen. Diese Cookies ermöglichen es uns, Ihren Browser beim nächsten Besuch wiederzuerkennen.<br /><br />
Sie können Ihren Browser so einstellen, dass Sie über das Setzen von Cookies informiert werden und Cookies nur im Einzelfall erlauben, die Annahme von Cookies für bestimmte Fälle oder generell ausschließen sowie das automatische Löschen der Cookies beim Schließen des Browser aktivieren. Bei der Deaktivierung von Cookies kann die Funktionalität dieser Website eingeschränkt sein.<br /><br />
Cookies, die zur Durchführung des elektronischen Kommunikationsvorgangs oder zur Bereitstellung bestimmter, von Ihnen erwünschter Funktionen (z.B. Warenkorbfunktion) erforderlich sind, werden auf Grundlage von Art. 6 Abs. 1 lit. f DSGVO gespeichert. Der Websitebetreiber hat ein berechtigtes Interesse an der Speicherung von Cookies zur technisch fehlerfreien und optimierten Bereitstellung seiner Dienste. Soweit andere Cookies (z.B. Cookies zur Analyse Ihres Surfverhaltens) gespeichert werden, werden diese in dieser Datenschutzerklärung gesondert behandelt.<br /><br />
<span class='content1'>Server-Log-Dateien</span><br /><br />
Der Provider der Seiten erhebt und speichert automatisch Informationen in so genannten Server-Log-Dateien, die Ihr Browser automatisch an uns übermittelt. Dies sind:<br /><br />
Browsertyp und Browserversion<br /> verwendetes Betriebssystem<br /> Referrer URL<br /> Hostname des zugreifenden Rechners<br /> Uhrzeit der Serveranfrage<br /> IP-Adresse<br /><br />
Eine Zusammenführung dieser Daten mit anderen Datenquellen wird nicht vorgenommen.<br /><br />
Grundlage für die Datenverarbeitung ist Art. 6 Abs. 1 lit. f DSGVO, der die Verarbeitung von Daten zur Erfüllung eines Vertrags oder vorvertraglicher Maßnahmen gestattet.<br /><br />
<span class='content1'>Kontaktformular</span><br /><br />
Wenn Sie uns per Kontaktformular Anfragen zukommen lassen, werden Ihre Angaben aus dem Anfrageformular inklusive der von Ihnen dort angegebenen Kontaktdaten zwecks Bearbeitung der Anfrage und für den Fall von Anschlussfragen bei uns gespeichert. Diese Daten geben wir nicht ohne Ihre Einwilligung weiter.<br /><br />
Die Verarbeitung der in das Kontaktformular eingegebenen Daten erfolgt somit ausschließlich auf Grundlage Ihrer Einwilligung (Art. 6 Abs. 1 lit. a DSGVO). Sie können diese Einwilligung jederzeit widerrufen. Dazu reicht eine formlose Mitteilung per E-Mail an uns. Die Rechtmäßigkeit der bis zum Widerruf erfolgten Datenverarbeitungsvorgänge bleibt vom Widerruf unberührt.<br /><br />
Die von Ihnen im Kontaktformular eingegebenen Daten verbleiben bei uns, bis Sie uns zur Löschung auffordern, Ihre Einwilligung zur Speicherung widerrufen oder der Zweck für die Datenspeicherung entfällt (z.B. nach abgeschlossener Bearbeitung Ihrer Anfrage). Zwingende gesetzliche Bestimmungen insbesondere Aufbewahrungsfristen bleiben unberührt.<br /><br />
<span class='content1'>Registrierung auf dieser Website</span><br /><br />
Sie können sich auf unserer Website registrieren, um zusätzliche Funktionen auf der Seite zu nutzen. Die dazu eingegebenen Daten verwenden wir nur zum Zwecke der Nutzung des jeweiligen Angebotes oder Dienstes, für den Sie sich registriert haben. Die bei der Registrierung abgefragten Pflichtangaben müssen vollständig angegeben werden. Anderenfalls werden wir die Registrierung ablehnen.<br /><br />
Für wichtige Änderungen etwa beim Angebotsumfang oder bei technisch notwendigen Änderungen nutzen wir die bei der Registrierung angegebene E-Mail-Adresse, um Sie auf diesem Wege zu informieren.<br /><br />
Die Verarbeitung der bei der Registrierung eingegebenen Daten erfolgt auf Grundlage Ihrer Einwilligung (Art. 6 Abs. 1 lit. a DSGVO). Sie können eine von Ihnen erteilte Einwilligung jederzeit widerrufen. Dazu reicht eine formlose Mitteilung per E-Mail an uns. Die Rechtmäßigkeit der bereits erfolgten Datenverarbeitung bleibt vom Widerruf unberührt.<br /><br />
Die bei der Registrierung erfassten Daten werden von uns gespeichert, solange Sie auf unserer Website registriert sind und werden anschließend gelöscht. Gesetzliche Aufbewahrungsfristen bleiben unberührt.<br /><br />
<span class='content1'>Verarbeiten von Daten (Kunden- und Vertragsdaten)</span><br /><br />
Wir erheben, verarbeiten und nutzen personenbezogene Daten nur, soweit sie für die Begründung, inhaltliche Ausgestaltung oder Änderung des Rechtsverhältnisses erforderlich sind (Bestandsdaten). Dies erfolgt auf Grundlage von Art. 6 Abs. 1 lit. b DSGVO, der die Verarbeitung von Daten zur Erfüllung eines Vertrags oder vorvertraglicher Maßnahmen gestattet. Personenbezogene Daten über die Inanspruchnahme unserer Internetseiten (Nutzungsdaten) erheben, verarbeiten und nutzen wir nur, soweit dies erforderlich ist, um dem Nutzer die Inanspruchnahme des Dienstes zu ermöglichen oder abzurechnen.<br /><br />
Die erhobenen Kundendaten werden nach Abschluss des Auftrags oder Beendigung der Geschäftsbeziehung gelöscht. Gesetzliche Aufbewahrungsfristen bleiben unberührt.<br /><br />
<span class='content1'>Datenübermittlung bei Vertragsschluss für Online-Shops, Händler und Warenversand</span><br /><br />
Wir übermitteln personenbezogene Daten an Dritte nur dann, wenn dies im Rahmen der Vertragsabwicklung notwendig ist, etwa an die mit der Lieferung der Ware betrauten Unternehmen oder das mit der Zahlungsabwicklung beauftragte Kreditinstitut. Eine weitergehende Übermittlung der Daten erfolgt nicht bzw. nur dann, wenn Sie der Übermittlung ausdrücklich zugestimmt haben. Eine Weitergabe Ihrer Daten an Dritte ohne ausdrückliche Einwilligung, etwa zu Zwecken der Werbung, erfolgt nicht.<br /><br />
Grundlage für die Datenverarbeitung ist Art. 6 Abs. 1 lit. b DSGVO, der die Verarbeitung von Daten zur Erfüllung eines Vertrags oder vorvertraglicher Maßnahmen gestattet.<br /><br />
<span class='content_title2'>4. Newsletter</span><br /><br />
<span class='content1'>Newsletterdaten</span><br /><br />
Wenn Sie den auf der Website angebotenen Newsletter beziehen möchten, benötigen wir von Ihnen eine E-Mail-Adresse sowie Informationen, welche uns die Überprüfung gestatten, dass Sie der Inhaber der angegebenen E-Mail-Adresse sind und mit dem Empfang des Newsletters einverstanden sind. Weitere Daten werden nicht bzw. nur auf freiwilliger Basis erhoben. Diese Daten verwenden wir ausschließlich für den Versand der angeforderten Informationen und geben diese nicht an Dritte weiter.<br /><br />
Die Verarbeitung der in das Newsletteranmeldeformular eingegebenen Daten erfolgt ausschließlich auf Grundlage Ihrer Einwilligung (Art. 6 Abs. 1 lit. a DSGVO). Die erteilte Einwilligung zur Speicherung der Daten, der E-Mail-Adresse sowie deren Nutzung zum Versand des Newsletters können Sie jederzeit widerrufen, etwa über den "Austragen"-Link im Newsletter. Die Rechtmäßigkeit der bereits erfolgten Datenverarbeitungsvorgänge bleibt vom Widerruf unberührt.<br /><br />
Die von Ihnen zum Zwecke des Newsletter-Bezugs bei uns hinterlegten Daten werden von uns bis zu Ihrer Austragung aus dem Newsletter gespeichert und nach der Abbestellung des Newsletters gelöscht. Daten, die zu anderen Zwecken bei uns gespeichert wurden (z.B. E-Mail-Adressen für den Mitgliederbereich) bleiben hiervon unberührt.<br /><br />
<span class='content_title2'>5. Plugins und Tools</span><br /><br />
<span class='content1'>Google Maps</span><br /><br />
Diese Seite nutzt über eine API den Kartendienst Google Maps. Anbieter ist die Google Inc., 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA.<br /><br />
Zur Nutzung der Funktionen von Google Maps ist es notwendig, Ihre IP Adresse zu speichern. Diese Informationen werden in der Regel an einen Server von Google in den USA übertragen und dort gespeichert. Der Anbieter dieser Seite hat keinen Einfluss auf diese Datenübertragung.<br /><br />
Die Nutzung von Google Maps erfolgt im Interesse einer ansprechenden Darstellung unserer Online-Angebote und an einer leichten Auffindbarkeit der von uns auf der Website angegebenen Orte. Dies stellt ein berechtigtes Interesse im Sinne von Art. 6 Abs. 1 lit. f DSGVO dar.<br /><br />
Mehr Informationen zum Umgang mit Nutzerdaten finden Sie in der Datenschutzerklärung von Google: https://www.google.de/intl/de/policies/privacy/.<br /><br />
<span class='content1'>Facebook-Plugin (Like-Button)</span><br /><br />
Auf unseren Seiten sind Plugins des sozialen Netzwerks Facebook (Facebook Inc., 1601 Willow Road, Menlo Park, California, 94025, USA) integriert. Die Facebook-Plugins erkennen Sie an dem Facebook-Logo oder dem "Like-Button" ("Gefällt mir") auf unserer Seite. Eine Übersicht über die Facebook-Plugins finden Sie hier: http://developers.facebook.com/docs/plugins/.<br />Wenn Sie unsere Seiten besuchen, wird über das Plugin eine direkte Verbindung zwischen Ihrem Browser und dem Facebook-Server hergestellt. Facebook erhält dadurch die Information, dass Sie mit Ihrer IP-Adresse unsere Seite besucht haben. Wenn Sie den Facebook "Like-Button" anklicken während Sie in Ihrem Facebook-Account eingeloggt sind, können Sie die Inhalte unserer Seiten auf Ihrem Facebook-Profil verlinken. Dadurch kann Facebook den Besuch unserer Seiten Ihrem Benutzerkonto zuordnen. Wir weisen darauf hin, dass wir als Anbieter der Seiten keine Kenntnis vom Inhalt der übermittelten Daten sowie deren Nutzung durch Facebook erhalten. Weitere Informationen hierzu finden Sie in der Datenschutzerklärung von facebook unter http://de-de.facebook.com/policy.php<br /><br />
Wenn Sie nicht wünschen, dass Facebook den Besuch unserer Seiten Ihrem Facebook-Nutzerkonto zuordnen kann, loggen Sie sich bitte aus Ihrem Facebook-Benutzerkonto aus.<br /><br />
<span class='content_title2'>6. Zahlungsanbieter</span><br /><br />
<span class='content1'>Payone</span><br /><br />
Auf unserer Website bieten wir u.a. die Bezahlung via Payone an. Anbieter dieses Zahlungsdienstes ist die BS PAYONE GmbH, Lyoner Straße 9, D-60528 Frankfurt/Main .<br /><br />
Wenn Sie die Bezahlung via Payone auswählen, werden die von Ihnen eingegebenen Zahlungsdaten an Payone übermittelt.<br /><br />
Die Übermittlung Ihrer Daten an Payone erfolgt auf Grundlage von Art. 6 Abs. 1 lit. a DSGVO (Einwilligung) und Art. 6 Abs. 1 lit. b DSGVO (Verarbeitung zur Erfüllung eines Vertrags). Sie haben die Möglichkeit, Ihre Einwilligung zur Datenverarbeitung jederzeit zu widerrufen. Ein Widerruf wirkt sich auf die Wirksamkeit von in der Vergangenheit liegenden Datenverarbeitungsvorgängen nicht aus.
</div>
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<style>
.ui-dialog .ui-dialog-content {
background: white;
}
.ui-dialog > .ui-widget-header {
color: white;
font-weight: normal;
border: 1px solid #0061a1;
background: #0061a1;
}
.ui-widget-overlay {
background: #666 url("https://app2.tink-konstanz.de/jquery-ui/images/ui-bg_diagonals-thick_20_666666_40x40.png") 50% 50% repeat;
opacity: .5;
filter: Alpha(Opacity=50);
}
</style>
</div>
</div>
<script src='https://app2.tink-konstanz.de/bootstrap-3.3.6-dist/js/bootstrap.min.js'></script>
</body>
</html>

View file

@ -0,0 +1,65 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK Konstanz</title>
<base href="https://tink-konstanz.de/TINK-Konstanz/Transportr%C3%A4der" />
<meta name="google-site-verification" content="_APrJWq--w-a4cD3sqOin3stmcxCvHpAVhV35E2sRnU" />
<meta name="viewport" content="width=device-width,target-densitydpi=device-dpi,initial-scale=1,user-scalable=yes" />
<meta name="description" content="Die TINK Konstanz Transporträder sind an ihren Stationen in den Stadtteilen Altstadt, Paradies und Petershausen aktuell mittels SMS anzumieten." />
<meta name="keywords" content="TINK, Konstanz, Transportrad, Lastenrad, Leihrad, Mieten, fahrradspezialitäten" />
<meta name="author" content="Dominik Langer" />
<meta name="copyright" content="Dominik Langer" />
<meta name="publisher" content="Dominik Langer" />
<link rel="manifest" href="" />
<link rel="shortcut icon" href="https://www2.tink-konstanz.de/img/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto+Condensed" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://www2.tink-konstanz.de/css/local_style.css");
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="">
<div class='container'>
<div id='Contenttxt'>
<div class="content_title2" id="2350">Impressum</div>
<div style=""></div>
<div class="content2_contact">Angaben gemäß § 5 TMG:<br /><br />
Dominik Langer<br />
Fahrradspezialitäten<br />
Marie-Curie-Str.1<br />
79100 Freiburg<br /><br />
eMail: tink@fahrradspezialitaeten.com<br />
Tel.: +49 761 453 700 99<br /> <br />
Umsatzsteuer-Identifikationsnummer gemäß §27 a Umsatzsteuergesetz:<br />
Umsatzsteuer-ID: DE815422380<br /><br />
Screendesign: Sebastian Krämer <a href='http://www.kartoffeldruck-media.de' target='_blank'>www.kartoffeldruck-media.de</a><br />
Programmierung: Rainer Gümpelein <a href='http://www.GNU-Systems.de' target='_blank'>www.GNU-Systems.de</a><br />
App: O. Hauff, gruks@posteo.eu<br /><br />
Irrtümer, Druck-/Schreibfehler, Preisänderungen und Liefermöglichkeit vorbehalten.<br /><br />
<span class='content1'>Haftungsausschluss (Disclaimer)</span><br /><br />
<span style='font-weight:bold'>Haftung für Inhalte</span><br />
Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.<br /><br />
<span style='font-weight:bold'>Haftung für Links</span><br />
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.<br /><br />
Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten durch Dritte zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit ausdrücklich widersprochen. Die Betreiber der Seiten behalten sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-Mails, vor.<br /><br /> <br />
<div style="clear:both;"></div>
<div class="content2_contact">&nbsp;</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,668 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK-App</title>
<meta name="viewport" content="width=device-width,target-densitydpi=device-dpi,initial-scale=1,user-scalable=yes" />
<link rel="manifest" href="" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto+Condensed" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://www2.tink-konstanz.de/css/local_style.css");
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<div class='container'>
<div id='Contenttxt'>
<div class="content_title2">Version</div>
<div style=""></div>
<br />Version ACTIVE_APPNAME: <b>CURRENT_VERSION_TINKAPP</b>.
<div class="content_title2">Entwickler</div>
<div style=""></div>
<br />Programmierung ACTIVE_APPNAME: O. Hauff, o.hauff@sharee.bike.<br />
<div class="content_title2">Verwendete Bibliotheken</div>
<div style=""></div>
<br /><table>
<tr><th>Paket </th><th>Lizenz </th></tr>
<tr><td>Newtonsoft Json.NET von James Newton-King </td><td><a href="#MITLicense2007">MIT Lizenz 2007</a> </td></tr>
<tr><td>PCLCrypto von AArnott </td><td><a href="#MSPL_Long">Microsoft Public License(Ms-PL)</a> </td></tr>
<tr><td>PCLStorage von Daniel Plaisted </td><td><a href="#MSPL_Long">Microsoft Public License (Ms-PL)</a> </td></tr>
<tr><td>Pinvoke von AArnott </td><td><a href="#MITLicenseAArnott">MIT- Lizenz für Pinvoke</a> </td></tr>
<tr><td>Plugin.BLE Adrian Seceleanu, Sven-Michael Stübe </td><td><a href="#ApacheLicense2.0_2004">Apache License 2.0</a> </td></tr>
<tr><td>Plugin.Permissions von James Montemagno </td><td><a href="#MITLicenseMontemagno2016">MIT Lizenz 2016</a> </td></tr>
<tr><td>Polly von Michael Wolfenden, App vNext </td><td><a href="#NewBSDLicense">New BSD License</a> </td></tr>
<tr><td>Serilog von Serilog Contributors </td><td><a href="#ApacheLicense2.0_2004">Apache License 2.0</a> </td></tr>
<tr><td>Serilog.Sinks.Debug von Serilog Contributors </td><td><a href="#ApacheLicense2.0_2004">Apache License 2.0</a> </td></tr>
<tr><td>Serilog.Sinks.File von Serilog Contributors </td><td><a href="#ApacheLicense2.0_2004">Apache License 2.0</a> </td></tr>
<tr><td>Serilog.Sinks.Xaramri von Serilog Contributors </td><td><a href="#ApacheLicense2.0_2004">Apache License 2.0</a> </td></tr>
<tr><td>Validation von AArnott </td><td><a href="#MSPL_Short">Microsoft Public License (MS-PL)</a> </td></tr>
<tr><td>Xam.Plugins.Messaging von Carel Lotz </td><td><a href="#MITLicense2014">MIT Lizenz 2014</a> </td></tr>
<tr><td>MonkeyCache von James Montemagno </td><td><a href="#MITLicense2018">MIT Lizenz 2018</a> </td></tr>
<tr><td>Xam.Plugin.Connectivity von James Montemagno </td><td><a href="#MITLicenseMontemagnoLCC2016">MIT Lizenz 2016</a> </td></tr>
<tr><td>Xamarin.Forms.GoogleMaps von amay077 </td><td><a href="#MITLicense2016_2017">MIT Lizenz 2016- 2017</a> </td></tr>
<tr><td>Xamarin.Essentials von Microsoft </td><td><a href="#MITLicenseMicrosoft">MIT Lizenz</a> </td></tr>
</table>
<div class="content_title2">Lizenzen</div>
<div style=""></div>
<article id="ApacheLicense2.0_2004">
<div class="content2">
<span class='content1'>Apache License</span><br />
<p>Version 2.0, January 2004</p>
<p>www.apache.org</p>
<p>TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION</p>
<p>
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
</p>
<p>
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
</p>
<p>
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
</p>
<p>
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
</p>
<p>
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
</p>
<p>
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
</p>
<p>
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
</p>
<p>
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
</p>
<p>
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
</p>
<p>
END OF TERMS AND CONDITIONS
</p>
<p>
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</p>
</div>
</article>
<article id="MSPL_Long">
<div class="content2">
<span class='content1'>Microsoft Public License (Ms-PL)</span><br />
<p>
This license governs use of the accompanying software. If you use the software,
you accept this license. If you do not accept the license, do not use the
software.
</p>
<p>1. Definitions</p>
<p>
The terms "reproduce," "reproduction," "derivative works," and "distribution"
have the same meaning here as under U.S. copyright law.
</p>
<p>
A "contribution" is the original software, or any additions or changes to the
software.
</p>
<p>
A "contributor" is any person that distributes its contribution under this
license.
</p>
<p>
"Licensed patents" are a contributor's patent claims that read directly on its
contribution.
</p>
<p>2. Grant of Rights</p>
<p>
(A) Copyright Grant- Subject to the terms of this license, including the license
conditions and limitations in section 3, each contributor grants you a
non-exclusive, worldwide, royalty-free copyright license to reproduce its
contribution, prepare derivative works of its contribution, and distribute its
contribution or any derivative works that you create.
</p>
<p>
(B) Patent Grant- Subject to the terms of this license, including the license
conditions and limitations in section 3, each contributor grants you a
non-exclusive, worldwide, royalty-free license under its licensed patents to
make, have made, use, sell, offer for sale, import, and/or otherwise dispose of
its contribution in the software or derivative works of the contribution in the
software.
</p>
<p>3. Conditions and Limitations</p>
<p>
(A) No Trademark License- This license does not grant you rights to use any
contributors' name, logo, or trademarks.
</p>
<p>
(B) If you bring a patent claim against any contributor over patents that you
claim are infringed by the software, your patent license from such contributor
to the software ends automatically.
</p>
<p>
(C) If you distribute any portion of the software, you must retain all
copyright, patent, trademark, and attribution notices that are present in the
software.
</p>
<p>
(D) If you distribute any portion of the software in source code form, you may
do so only under this license by including a complete copy of this license with
your distribution. If you distribute any portion of the software in compiled or
object code form, you may only do so under a license that complies with this
license.
</p>
<p>
(E) The software is licensed "as-is." You bear the risk of using it. The
contributors give no express warranties, guarantees or conditions. You may have
additional consumer rights under your local laws which this license cannot
change. To the extent permitted under your local laws, the contributors exclude
the implied warranties of merchantability, fitness for a particular purpose and
non-infringement.
</p>
</div>
</article>
<article id="MSPL_Short">
<div class="content2">
<span class='content1'>Microsoft Public License (MS-PL)</span><br />
<p>
This license governs use of the accompanying software. If you use the software, you
accept this license. If you do not accept the license, do not use the software.
</p>
<p>1. Definitions</p>
<p>
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
</p>
<p>2. Grant of Rights</p>
<p>
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
</p>
<p>
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
</p>
<p>3. Conditions and Limitations</p>
<p>
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
</p>
<p>
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
</p>
<p>
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
</p>
<p>
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
</p>
<p>
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
</p>
</div>
</article>
<article id="MITLicenseAArnott">
<div class="content2">
<span class='content1'>MIT- Lizenz für Pinvoke von AArnott</span><br />
<p>
The following license applies to all files in this project unless specified otherwise
within individual files.
See also the COPYRIGHT.md file.
</p>
<p>The MIT License (MIT)</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
</p>
</div>
</article>
<article id="MITLicense2007">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>Copyright (c) 2007 James Newton-King</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the /"Software/"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</p>
</div>
</article>
<article id="MITLicense2014">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>Copyright (c) 2014 Carel Lotz</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</p>
</div>
</article>
<article id="MITLicense2016_2017">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>Copyright (c) amay077 2016 - 2017</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</p>
</div>
</article>
<article id="MITLicense2018">
<div class="content2">
<span class='content1'>MIT License</span><br />
<p>Copyright (c) 2018 James Montemagno</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</p>
</div>
</article>
<article id="MITLicenseMontemagnoLCC2016">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>
Copyright (c) 2016 James Montemagno / Refractored LLC
</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</p>
</div>
</article>
<article id="NewBSDLicense">
<div class="content2">
<span class='content1'>New BSD License</span><br />
<p>
Copyright (c) 2015-2020, App vNext<br />
All rights reserved.
</p>
<p>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
<ul>
<li/> Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
<li /> Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
<li /> Neither the name of App vNext nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
</ul>
</p>
<p>
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</p>
</div>
</article>
<article id="MITLicenseMicrosoft">
<div class="content2">
<p>Xamarin.Essentials</p>
<span class='content1'>The MIT License (MIT)</span><br />
<p>Copyright (c) Microsoft Corporation</p>
<p>All rights reserved.</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</p>
</div>
</article>
<article id="MITLicenseMontemagno2016">
<div class="content2">
<span class='content1'>The MIT License (MIT)</span><br />
<p>
Copyright (c) 2016 James Montemagno
</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</p>
</div>
</article>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,150 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK Konstanz</title>
<base href="https://tink-konstanz.de/TINK-Konstanz/Transportr%C3%A4der" />
<meta name="google-site-verification" content="_APrJWq--w-a4cD3sqOin3stmcxCvHpAVhV35E2sRnU" />
<meta name="viewport" content="width=device-width,target-densitydpi=device-dpi,initial-scale=1,user-scalable=yes" />
<meta name="description" content="Die TINK Konstanz Transporträder sind an ihren Stationen in den Stadtteilen Altstadt, Paradies und Petershausen aktuell mittels SMS anzumieten." />
<meta name="keywords" content="TINK, Konstanz, Transportrad, Lastenrad, Leihrad, Mieten, fahrradspezialitäten" />
<meta name="author" content="Dominik Langer" />
<meta name="copyright" content="Dominik Langer" />
<meta name="publisher" content="Dominik Langer" />
<link rel="manifest" href="" />
<link rel="shortcut icon" href="https://www2.tink-konstanz.de/img/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto+Condensed" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://www2.tink-konstanz.de/css/local_style.css");
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="">
<div class='container'>
<div id='Contenttxt'>
<div class="content_title2" id="2344">TARIFE</div>
<div style=""></div>
<div class="content2">
<span class='content12'>
konrad
</span><br />
Jede angefangene 1/2 Stunde 1 Euro bis maximal 9 Euro für 24 Stunden.<br />
1/2 Stunde kostenlos für unsere Stadtwerke Stammkunden - mehr Infos <a href="https://www.stadtwerke-konstanz.de/mobilitaet/rad-mietsystem/bonus-fuer-kunden/"> hier.</a><br />
<br />
<span class='content12'>
TINK
</span><br />
Jede angefangene 1/2 Stunde kostet 1,50 Euro.<br />
Max. 15 Euro für 24 Stunden.<br />
Die erste 1/2 Stunde kostenlos für unsere Stadtwerke Stammkunden - mehr Infos <a href="https://www.stadtwerke-konstanz.de/mobilitaet/rad-mietsystem/bonus-fuer-kunden/">hier</a> .
</div>
<div class="content_title2" id="2344">LEIHSTATIONEN IN KONSTANZ</div>
<div style=""></div>
<div class="content2">
<span class='content12'>
konrad
</span><br />
Das sind die Standorte der Fahrräder: Bahnhof Konstanz, Döbeleplatz, Laube, HTWG, Mobilpunkt Seerhein (P+R-Parkplatz Schänzlebrücke), Zähringerplatz, Bahnhof Petershausen, Bahnhof Fürstenberg, Bahnhof Wollmatingen, Fürstenberg (an der Bushaltestelle Herosestraße), Universität, Allmannsdorf (Bushaltestelle Mainaustraße am „Penny“-Markt) , Fähranleger Staad, Kreuzung Von-Emmich-Str./ St.-Gebhard-Str., Eichhornstr. (Hörnle) und Mainau.<br />
<br />
<span class='content12'>
TINK
</span><br />
Das sind die Standorte der Transporträder: Bahnhof Konstanz, Döbeleplatz, Laube, St.-Stephans-Platz, Europahaus (SEEZEIT), FRISTO Getränkemarkt, ggü. Fahrradspezialitaeten (Laden), Ellenrieder Gymnasium, Treffpunkt Petershausen, Kreuzung Markgrafenstr./Alemannenstr., Kreuzung Von Emmich Str./ St. Gebhard Str., Bahnhof Petershausen, LAGO Shopping-Center<br />
</div>
<div style="clear:both;"></div>
<div class="content_title2" id="2344">WIE FUNKTIONIERT'S</div>
<div style=""></div>
<div class="content2">
<span class='content12'>1. Erstmalige Registrierung</span><br />
Vor der ersten Anmietung eines Mietrades ist es notwendig, sich kostenlos als Nutzerin oder Nutzer zu registrieren. Das dauert nur wenige Minuten und geht am einfachsten über <a href='https://konrad.tink-konstanz.de/konrad/Anmelden'>konrad.tink-konstanz.de/konrad/Anmelden</a>. Sobald der Account freigeschaltet ist, kann es losgehen.<br />
<br />
<span class='content12'>2. Rad mieten<br /></span>
Soll<br />
<ul>
<li>ein Stadtrad gemietet werden bitte in der "Fahrradstandorte"-Ansicht auf den Knopf "Konrad" drücken wenn dieser noch ausgegraut ist</li>
<li>ein Lastenrad gemietet werden bitte in der "Fahrradstandorte"-Ansicht auf den Knopf "TINK" drücken wenn dieser noch ausgegraut ist</li>
</ul>
Jetzt werden alle Stationen grün markiert, an denen Räder vom gewünschten Typ verfügbar sind.
Einfach zur nächsten in der Kartenansicht grün markierten Station gehen und den Code für den Bordcomputer wie im folgenden beschrieben per TINK-App anfordern oder das Rad per RFID-Chip buchen. Die RFID-Chips gibt es gegen Kaution von 5 Euro beifahrradspezialitaeten-Konstanz in der Schulthaißstraße 1a, im Energiewürfel der Stadtwerke Konstanz oder sie werden auf Wunsch zugeschickt.<br />
Die Buchung per App funktioniert unterschiedlich, abhängig davon, ob ein Rad mit Bordcomputer ausgestattet ist oder nicht.<br /><br />
<b>Buchung mit App von Rad mit Bordcomputer.</b><br />
Fast alle Räder sind mittlerweise mit Bordcomputer ausgestattet.
<ul>
<li>Wählen Sie Ihre Station in der "Fahrradstandorte"-Ansicht aus und tippen Sie dann in der Liste der an der Station verfügbaren Räder auf das Fahrrad, das Sie mieten möchten</li>
<li>Am Bordcomputer die Option "Code" auswählen und den in der App beim zu mietenden Rad angezeigten Zahlencode eingeben. Das Schloss öffnet automatisch. Das Rad ist erst gemietet, sobald Sie den Zahlencode eingegeben haben. Falls Sie das nicht tun verfällt der Code nach 15 Minuten. </li>
</ul>
<b>Buchung mit App von Rad ohne Bordcomputer</b><br />
Um diesen Service nutzen zu können muss ihre Mobiltelefonnummer in ihrem Account hinterlegt sein. Einige Lastenräder besitzen noch keinen Bordcomputer. Hier erfolgt die Buchung ausschließlich mit SMS.
<ul>
<li>Wählen Sie Ihre Station in der "Fahrradstandorte"-Ansicht aus und tippen Sie dann in der Liste der an der Station verfügbaren Räder auf das Fahrrad, das Sie mieten möchten</li>
<li>Die TINK-App öffnet automatisch die SMS- App Ihres Smartphons mit SMS- Entwurf an +49 176 43852920 und mit der Radnummer als Text. Die SMS muss muss nur noch abgeschickt werden. Zur Info: Die Radnummer findet sich am Rahmen unterhalb des Sattels.</li>
<li>Antwort-SMS mit vierstelligem Code abwarten</li>
<li>Zahlenschloss durch Einstellen von Code öffnen. </li>
</ul>
<b>SMS-Buchung ohne App</b><br />
Um diesen Service nutzen zu können muss ihre Mobiltelefonnummer in ihrem Account hinterlegt sein. Diese Buchungsart kann für alle Räder durchgeführt werden.<br />
<ul>
<li>SMS mit der Radnummer (am Rahmen unterhalb des Sattels) an die +49 176 43852920 versenden</li>
<li>Antwort-SMS mit vierstelligem Code abwarten</li>
<li>Für ein Rad mit Bodcomputer am Bordcomputer die Option "Code" auswählen und Zahlencode eingeben. Das Schloss öffnet automatisch. Das Rad ist erst gemietet, sobald Sie den Zahlencode eingegeben haben. Falls Sie das nicht tun verfällt der Code nach 15 Minuten.</li>
<li>Für ein Rad ohne Bodcomputer Zahlenschloss durch Einstellen von Code öffnen.</li>
</ul>
<b>per Chip</b><br />
<ul>
<li>Am Bordcomputer die Option "Chip" auswählen</li>
<li>RFID Chip an markierter Stelle (rechts neben der Tastatur) anhalten</li>
<li>Sobald der RFID Chip erkannt ist öffnet das Schloss automatisch. </li>
</ul>
<br />
<span class="content12">3. Rad nutzen</span><br />
<div style=""></div>
Das Rad kann während der Mietzeit abgeschlossen werden, einfach die Funktion Parken über den Bordcomputer wählen, z.B. beim Einkaufen. Es kann mit dem bestehenden Code erneut geöffnet
werden.
<div style="clear:both;"></div><br />
<sapn class="content12">4. Abgabe</sapn>
<div style=""></div>
<b>Mit Bordcomputer (konrad und TINK):</b>
<ul>
<li>konrad: Rad kann nur (!) an einer (beliebigen) konrad-Station zurückgegeben werden.</li>
<li>TINK: Rad kann nur (!) an einer (beliebigen) TINK-Station zurückgegeben werden.</li>
<li>Räder, die ausserhalb einer Station abgegeben werden, werden kostenpflichtig zur nächsten Station zurückgebracht.</li>
<li>Funktion "Rückgabe" wählen, indem Sie die Taste 2 drücken.</li>
<li>Frage über Defekt des Rades beantworten. Falls Sie einen Defekt bemerken, würden wir uns freuen, wenn Sie uns diesen im Anschluss genauer via Mail beschreiben können. E-Mail: konrad@fahrradspezialitaeten.com.</li>
<li>
konrad: Sicherungsseil einstecken und das Speichenschloss (am Hinterrad) per Hand verriegeln.
Rad muss durch Sicherungsseil gesichert sein - sofern ein Sicherungsseil frei ist!
Ohne verschlossenem Speichenschloss ist der Mietvorgang noch nicht beendet!
</li>
<li>
TINK: Mit Zahlenschloss am Ankerseil anschließen.
Rad muss durch das Ankerseil gesichert sein!
</li>
<li>
Erst wenn der Bordcomputer "Mietvorgang beendet, danke sagt dein Leihrad!" anzeigt, ist der Mietvorgang beendet.
</li>
</ul>
<b>Mit Zahlenschloss (TINK):</b>
<ul>
<li>Rad kann nur an einer (beliebigen) TINK-Station zurückgegeben werden. </li>
<li>
Mit Zahlenschloss am Ankerseil anschließen.
Rad muss durch das Ankerseil gesichert sein!
</li>
<li>Stationsnummer oben/ seitlich auf dem TINK Schild ablesen. </li>
<li>SMS an die +49 176 43852920 mit folgendem Inhalt versenden: "Schlosscode, Stationsnummer".</li>
<li>Rückgabebestätigung (per SMS) abwarten.</li>
<li>Erst nach Erhalt der Bestätigung per SMS ist der Mietvorgang beendet.</li>
</ul>
</div>
<div style="clear:both;"></div>
Die meisten Fragen und Antworten finden Sie <a href="https://www.stadtwerke-konstanz.de/mobilitaet/rad-mietsystem/fragen-und-antworten/">hier</a>.
<div class="content2">&nbsp;</div>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,127 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head>
<title>TINK Konstanz</title>
<base href="https://tink-konstanz.de/TINK-Konstanz/Anleitungen" />
<meta name="copyright" content="Dominik Langer" />
<meta name="publisher" content="Dominik Langer" />
<meta name="author" content="Dominik Langer" />
<meta name="keywords" content="TINK, Konstanz, Transportrad, Lastenrad, Leihrad, Mieten, fahrradspezialitäten" />
<meta name="google-site-verification" content="_APrJWq--w-a4cD3sqOin3stmcxCvHpAVhV35E2sRnU" />
<meta name="description" content="Die TINK Konstanz Transporträder sind an ihren Stationen in den Stadtteilen Altstadt, Paradies und Petershausen aktuell mittels SMS anzumieten." />
<meta name="viewport" content="width=device-width,target-densitydpi=device-dpi,initial-scale=1,user-scalable=yes" />
<link href="" rel="manifest" />
<link type="image/x-icon" rel="shortcut icon" href="https://www2.tink-konstanz.de/img/favicon.ico" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/css/local_style.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/bootstrap-3.3.6-dist/css/bootstrap.css" media="screen" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto+Condensed" media="screen" />
<link rel="stylesheet" type="text/css" href="https://www2.tink-konstanz.de/jquery-ui/jquery-ui.min.css" media="screen" />
<style type="text/css">
@import url("https://www2.tink-konstanz.de/css/local_style.css");
</style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="">
<div class='container'>
<div id='Contenttxt'>
<div id="2358" class="content_title2">WELCHE TRANSPORTRÄDER GIBT ES BEI TINK?</div>
<div style=""></div>
<div class="content2"><span class='content1'>Zweirädriges Transportrad mit Platz für zwei Getränkekisten, Zuladung bis 80 kg. <br />Dreirädriges Transportrad sogar mit Platz für vier Getränkekisten, Zuladung bis 100 kg.</span><br />Jedes Rad verfügt über eine leichtgängige Achtgang-Schaltung und einen höhenverstellbaren Sattel. Im Zweirad können 2 Kinder, im Dreirad sogar 4 Kinder bis 6 Jahre mitgenommen werden. Die wegklappbaren Kindersitze verfügen über Sicherheitsgurte.<br />Die Räder sind nach etwas Gewöhnung leicht und sicher zu fahren. Vor der ersten Nutzung empfehlen wir ein kurzes Üben ohne Beladung abseits des Straßenverkehrs. Einfach mal ausprobieren, es macht richtig Spaß!<br /><span>&nbsp;</span></div>
<img src="https://www2.tink-konstanz.de/data/200001-resize/2358/TINK Papa Kind_RZ.jpg:282:188.jpg" id="pic-float" />
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200001-resize/2358/TINK_Jan_Krissi_Imperia_RZ.jpg:188:188.jpg" />
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200001-resize/2358/TINK_Krissi_Hafen_RZ.jpg:282:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div id="3402" class="content_title2">Zweirädriges TINK Rad: Hochklappen des Fahrradständers</div>
<div style=""></div>
<div class="content2">So abgestellt hat das zweirädrige Transportrad<br />einen sicheren Stand.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3402/image.4HJ5PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Zum Weiterfahren das Transportrad nach vorne bewegen,<br />bis kein Gewicht mehr auf dem Fahrradständer liegt.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3403/image.RIX2PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Den Fahrradständer mit dem Fuß nach oben drücken, bis er<br />hörbar am Magneten (Pfeil) einrastet. So fällt er unterwegs nicht<br />herunter.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3404/image.FDR7PY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div class="content_title2" id="3406">Dreirädriges TINK Rad: Lösen und Aktivieren der Feststellbremse</div>
<div style=""></div>
<div class="content2">Die Feststellbremse ist der graue Stift, der aus der Bremse<br />herausragt. Ist sie aktiv, kann das Dreirad nicht wegrollen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3406/image.HZ17PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Lösen der Feststellbremse: Die Bremse vollständig anziehen, bis<br />der Stift wieder auf seine ursprüngliche Position herausspringt.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3407/image.1YBAQY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Aktivieren der Feststellbremse: Die Bremse vollständig anziehen<br />und den Stift hineindrücken.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3408/image.FJM2PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div class="content_title2" id="3409">Höhenregulierung des Sattels</div>
<div style=""></div>
<div class="content2">Hier im Bild ist der Hebel zum Einstellen des Sattels zu sehen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3409/image.ZQ65PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Durch Drücken des Hebels ist die Sattelhöhe frei verstellbar.<br />Vergleichbar mit einem Bürostuhl bewegt sich der Sattel<br />automatisch nach oben.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3410/image.QQZCQY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Durch kräftiges Herunterdrücken des Sattels (und gleichzeitigem Betätigen des Hebels) kann der Sattel nach unten verstellt werden. Tipp: Eventuell draufsetzen und dann den Hebel betätigen, um den Sattel nach unten zu drücken.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3411/image.NQ5FQY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div class="content_title2" id="3412">Verbinden des Kindergurts</div>
<div style=""></div>
<div class="content2">Der Gurt besteht aus drei Einzelteilen. Zunächst die oberen<br />beiden Einzelstücke nehmen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3412/image.4XWCQY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Die beiden Einzelstücke zusammenfügen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3413/image.X3F1PY.png:334:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Das obere und untere Teilstück verbinden (bis zum Einrasten).<br />Lösen der Teilstücke durch Drücken auf den roten Knopf.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3414/image.DYOXPY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div id="3415" class="content_title2">Anschließen des Transportrades</div>
<div style=""></div>
<div class="content2">Für das richtige Anschließen des Transportrades wird das<br />Sicherungsseil (hängt an der Station) und das Zahlenschloss<br />benötigt. Das Zahlenschloss bleibt immer beim Rad!</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3415/image.IRL8PY.png:334:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Das Schloss durch die Schlaufe des Sicherheitsseiles ziehen.</div>
<img id="pic-float" src="https://www2.tink-konstanz.de/data/200015-resize/3416/image.831ZPY.png:354:188.jpg" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div style=""></div>
<div class="content2">Das Schloss um das Hinterrad und den Rahmen schließen. Sollte kein<br />Sicherheitsseil mehr verfügbar sein (weil bereits mindestens drei<br />Transporträder an der Station stehen), dann das Zahlenschloss einfach<br />ohne Sicherungsseil um das Hinterrad und den Rahmen schließen, wenn<br />möglich an eine Stütze der Station.</div>
<img src="https://www2.tink-konstanz.de/data/200015-resize/3418/image.J6NIQY.png:333:188.jpg" id="pic-float" />
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
<div class="content_title2" id="3419">Rückmeldungen und Fragen an info@tink.bike</div>
<div style=""></div>
<div class="content2">Information erstellt von:<br />Marco Walter, Simon Loferer, Nathalie Niekisch<br />e-fect eG</div>
<div style="clear:both;"></div>
<div class="content2">&nbsp;</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,004 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 500 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>{5CF95CB1-AD37-4DBA-8B9D-651CFB9EB903}</ProjectGuid>
<ReleaseVersion>3.0</ReleaseVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<PropertyGroup />
<Import Project="TINK.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>

View file

@ -0,0 +1,24 @@
using TINK.Model.Device;
using Xamarin.Forms;
namespace TINK.Model.Device
{
public class SpecialFolder : ISpecialFolder
{
/// <summary>
/// Get the folder name of external folder to write to.
/// </summary>
/// <returns></returns>
public string GetExternalFilesDir()
{
return DependencyService.Get<ISpecialFolder>().GetExternalFilesDir();
}
/// <summary> Gets the folder name of the personal data folder dir on internal storage. </summary>
/// <returns>Directory name.</returns>
public string GetInternalPersonalDir()
{
return DependencyService.Get<ISpecialFolder>().GetInternalPersonalDir();
}
}
}

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html xml:lang="de" lang="de">
<title>TINK Konstanz</title>
<meta charset="utf-8"/>
<body>
<h1>WIE FUNKTIONIERT DAS TRANSPORTRAD-MIETEN?</h1>
<h2>Erstmalige Registrierung</h2><br>
Vor der ersten Anmietung eines Transportrades ist es notwendig, sich
kostenlos als Nutzerin oder Nutzer zu registrieren. Das dauert nur
wenige Minuten und geht am einfachsten über den <a href="https://tink-konstanz.de/TINK-Konstanz/Mieten">Mieten</a> Button. Sobald der Account freigeschaltet ist, kann es losgehen.<br><br>
<h2>Transportrad mieten</h2><br>
Einfach zur nächsten TINK Station gehen (freie Räder siehe Karte) und den Code
für das Zahlenschloss mittels SMS anfordern. Die Anleitung, wie es genau
geht, findet sich direkt an den Stationen, auf den Rädern oder hier: <br><a href="https://tink-konstanz.de/TINK-Konstanz/Anleitungen#3401">
<li>Anleitung Mietvorgang</a><br><a href="https://tink-konstanz.de/TINK-Konstanz/Anleitungen#3402">
<li>Anleitung TINK Räder</a><br>
<span style="font-weight:bold"> <li>Wichtig:</span> Nach der Nutzung das Rad an eine der TINK Stationen zurückbringen, an der Station anschließen und mittels SMS ausloggen.<br><br>
Die erste Version der TINK APP ist verfügbar. Wir freuen uns auf konstruktives feedback.
<br><br><h2>Preise</h2><br>
Die erste Stunde pro Tag ist kostenfrei, danach kostet jede weitere halbe Stunde 1 Euro. Maximal
kostet ein Rad pro 24 Stunden 9 Euro. Es kann ein Rad pro Account
gemietet werden. Bezahlung per Abbuchung oder Kreditkarte.<br>Servicegebühren:
Bei Abstellen eines Rades außerhalb der Stationen werden
entfernungsabhängige Gebühren für die Rückführung berechnet. Aktuelle
Preisliste siehe AGBs.</div>
<h1>WELCHE TRANSPORTRÄDER GIBT ES BEI TINK?</h1>
<div class="content2"><span class="content1">Zweirädriges Transportrad mit Platz für zwei Getränkekisten, Zuladung bis 80 kg. <br>Dreirädriges Transportrad sogar mit Platz für vier Getränkekisten, Zuladung bis 100 kg.</span><br>Jedes
Rad verfügt über eine leichtgängige Achtgang-Schaltung und einen
höhenverstellbaren Sattel. Im Zweirad können 2 Kinder, im Dreirad sogar 4
Kinder bis 6 Jahre mitgenommen werden. Die wegklappbaren Kindersitze
verfügen über Sicherheitsgurte.<br>Die Räder sind nach etwas Gewöhnung
leicht und sicher zu fahren. Vor der ersten Nutzung empfehlen wir ein
kurzes Üben ohne Beladung abseits des Straßenverkehrs. Einfach mal
ausprobieren, es macht richtig Spaß!
</body>
</html>

View file

@ -0,0 +1,97 @@
#if ARENDI
using Arendi.BleLibrary;
using Arendi.BleLibrary.Adapter;
using Arendi.BleLibrary.Local;
using Arendi.BleLibrary.Remote;
#endif
using System;
using System.Collections.Generic;
using System.Text;
namespace TINK.Services.BluetoothLock.Arendi
{
#if ARENDI
public class Central : ICentral
#else
public class Central
#endif
{
#if ARENDI
private bool disposedValue;
public IAdapter Adapter => throw new NotImplementedException();
public BluetoothState BluetoothState => throw new NotImplementedException();
public ISecurityManager SecurityManager => throw new NotImplementedException();
public IBondManager BondManager => throw new NotImplementedException();
public IDictionary<string, string> SystemInformation => throw new NotImplementedException();
public event EventHandler<PeripheralDiscoveredEventArgs> PeripheralDiscovered;
public event EventHandler<BluetoothStateChangedEventArgs> BluetoothStateChanged;
public event EventHandler<EventArgs> SystemInformationUpdated;
public event EventHandler<FatalErrorEventArgs> FatalError;
public IPeripheral CreatePeripheralByUuid(Uuid uuid, string name = null)
{
throw new NotImplementedException();
}
public bool IsEnabled()
{
throw new NotImplementedException();
}
public void StartScan()
{
throw new NotImplementedException();
}
public void StartScan(string[] uuids)
{
throw new NotImplementedException();
}
public void StartScan(Uuid[] uuids)
{
throw new NotImplementedException();
}
public void StopScan()
{
throw new NotImplementedException();
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects)
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
}
}
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
// ~Central()
// {
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
// Dispose(disposing: false);
// }
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
#endif
}
}

View file

@ -0,0 +1,347 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>5297504f-603f-4e1a-98aa-57c4a0d9d833</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>TINK</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)BackdoorMethodHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\BluetoothLock\Arendi\Central.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootShell\AppShellViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootFlyout\RootPageViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\Account\AccountPage.xaml.cs">
<SubType>Code</SubType>
<DependentUpon>%(Filename)</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Bike\BCBike.xaml.cs">
<DependentUpon>BCBike.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Bike\BikeViewCellTemplateSelector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\Bike\ILockItBike.xaml.cs">
<DependentUpon>ILockItBike.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\BoolInverterConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\Contact\SelectStationPage.xaml.cs">
<DependentUpon>SelectStationPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\FeedbackPopup.xaml.cs">
<DependentUpon>FeedbackPopup.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\FindBike\FindBikePage.xaml.cs">
<DependentUpon>FindBikePage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\ListViewAttachedBehavior.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\MiniSurvey\MiniSurveyPage.xaml.cs">
<DependentUpon>MiniSurveyPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\MiniSurvey\Question\CheckOneViewCell.xaml.cs">
<DependentUpon>CheckOneViewCell.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\MiniSurvey\Question\FreeTextViewCell.xaml.cs">
<DependentUpon>FreeTextViewCell.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\MiniSurvey\Question\QuestionViewCellTemplateSelector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\RootShell\FlyoutHeader.xaml.cs">
<DependentUpon>FlyoutHeader.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPage.xaml.cs">
<DependentUpon>RootPage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyout.xaml.cs">
<DependentUpon>RootPageFlyout.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyoutMenuItem.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\Settings\AnyPermissionToVisibleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\Settings\PermissionToVisibleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\RootShell\AppShell.xaml.cs">
<DependentUpon>AppShell.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\StringNotNullOrEmptyToVisibleConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\ViewTypesTypeProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Model\Device\SpecialFolder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\FeesAndBikes\FeesAndBikesPage.xaml.cs">
<DependentUpon>FeesAndBikesPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\CopriWebView\ManageAccountPage.xaml.cs">
<DependentUpon>ManageAccountPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\CopriWebView\RegisterPage.xaml.cs">
<DependentUpon>RegisterPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\CopriWebView\PasswordForgottenPage.xaml.cs">
<DependentUpon>PasswordForgottenPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\WhatsNew\Agb\AgbPage.xaml.cs">
<DependentUpon>AgbPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\WhatsNew\WhatsNewPage.xaml.cs">
<DependentUpon>WhatsNewPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\ViewModelResourceHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\RootMasterDetail\Helper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)View\BikesAtStation\BikesAtStationPage.xaml.cs">
<DependentUpon>BikesAtStationPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Contact\ContactPage.xaml.cs">
<DependentUpon>ContactPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Info\BikeInfo\BikeInfoCarouselPage.xaml.cs">
<DependentUpon>BikeInfoCarouselPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Info\InfoTabbedPage.xaml.cs">
<DependentUpon>InfoTabbedPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Login\LoginPage.xaml.cs">
<DependentUpon>LoginPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\RootMasterDetail\MainPageMenuItem.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Map\MapPage.xaml.cs">
<DependentUpon>MapPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\MyBikes\MyBikesPage.xaml.cs">
<DependentUpon>MyBikesPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)View\Settings\SettingsPage.xaml.cs">
<DependentUpon>SettingsPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)App.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V02\InfoAGB.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V02\InfoDatenschutz.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V02\InfoLicenses.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V02\InfoRentBike.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V02\InfoTypesOfBikes.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V02\InfoImpressum.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V01\InfoTypesOfBikes.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V01\InfoRentBike.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V01\InfoLicenses.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V01\InfoImpressum.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V01\InfoDatenschutz.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)HtmlResouces\V01\InfoAGB.html" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Account\AccountPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Login\LoginPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\BikesAtStation\BikesAtStationPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Contact\ContactPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Map\MapPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\MyBikes\MyBikesPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Folder Include="$(MSBuildThisFileDirectory)View\BikesAtStation\" />
<Folder Include="$(MSBuildThisFileDirectory)View\FeesAndBikes\" />
<Folder Include="$(MSBuildThisFileDirectory)View\Login\" />
<Folder Include="$(MSBuildThisFileDirectory)View\Map\" />
<Folder Include="$(MSBuildThisFileDirectory)View\MyBikes\" />
<Folder Include="$(MSBuildThisFileDirectory)HtmlResouces\V01\" />
<Folder Include="$(MSBuildThisFileDirectory)HtmlResouces\V02\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Settings\SettingsPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Info\BikeInfo\BikeInfoCarouselPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\trike_brake1_image.HZ17PY_678_382.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Info\InfoTabbedPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\belt1_image.4XWCQY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\belt2_image.X3F1PY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\belt3_image.DYOXPY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\seat1_image.ZQ65PY_680_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\seat2_image.QQZCQY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\seat3_image.NQ5FQY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\trike_brake2_image.1YBAQY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\trike_brake3_image.FJM2PY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\trike_stand1_image.4HJ5PY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\trike_stand2_image.RIX2PY_679_382.png" />
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\trike_stand3_image.FDR7PY_679_382.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\FeesAndBikes\FeesAndBikesPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\Tink2.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Images\Konrad.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\WhatsNew\WhatsNewPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\WhatsNew\Agb\AgbPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\CopriWebView\RegisterPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\CopriWebView\ManageAccountPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\CopriWebView\PasswordForgottenPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Bike\BCBike.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Bike\ILockItBike.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootFlyout\RootPageFlyout.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootShell\AppShell.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\RootShell\FlyoutHeader.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\FeedbackPopup.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\FindBike\FindBikePage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\Contact\SelectStationPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\MiniSurvey\MiniSurveyPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\MiniSurvey\Question\CheckOneViewCell.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)View\MiniSurvey\Question\FreeTextViewCell.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="TINK.View.Account.AccountPage">
<ContentPage.Content>
<Frame>
<StackLayout>
<Frame>
<StackLayout>
<Label Text="{Binding LoggedInInfo}" />
<Label IsVisible="{Binding IsBookingStateInfoVisible}"
Text="{Binding BookingStateInfo}" />
<Button Text="Persönliche Daten Verwalten"
Command="{Binding OnManageAccount}"
IsEnabled="{Binding IsLogoutPossible}"/>
<Button Text="Abmelden"
Command="{Binding OnLogoutRequest}"
IsEnabled="{Binding IsLogoutPossible}"/>
</StackLayout>
</Frame>
</StackLayout>
</Frame>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,155 @@
using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using System;
using TINK.Model.Device;
using TINK.ViewModel.Account;
namespace TINK.View.Account
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class AccountPage : ContentPage, IViewService, IDetailPage
#else
public partial class AccountPage : ContentPage, IViewService
#endif
{
/// <summary> Refernce to view model. </summary>
AccountPageViewModel m_oViewModel = null;
/// <summary> Constructs a account page. </summary>
public AccountPage()
{
InitializeComponent();
var l_oModel = App.ModelRoot;
m_oViewModel = new AccountPageViewModel(
l_oModel,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
this);
BindingContext = m_oViewModel;
}
/// <summary> Displays alert message. </summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="cancel">Type of buttons.</param>
public new async Task DisplayAlert(string title, string message, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
/// <summary>
/// Displays an action sheet.
/// </summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="cancel">Text of button.</param>
/// <param name="destruction"></param>
/// <param name="p_oButtons">Buttons holding options to select.</param>
/// <returns>Text selected</returns>
public new async Task<string> DisplayActionSheet(String title, String cancel, String destruction, params String[] p_oButtons)
=> await base.DisplayActionSheet(title, cancel, destruction, p_oButtons);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string title = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushModalAsync(ViewTypes typeOfPage)
=> Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync()
=> throw new NotSupportedException();
#if USEFLYOUT
/// <summary>Delegate to perform navigation.</summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
protected async override void OnAppearing()
=> await m_oViewModel.OnAppearing();
/// <summary>
/// Invoked when pages is closed/ hidden.
/// Stops update process.
/// </summary>
protected async override void OnDisappearing()
{
if (m_oViewModel == null)
{
// View model might be null.
return;
}
await m_oViewModel.OnDisappearing();
}
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes p_oTypeOfPage)
=> await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#endif
}
}

View file

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:conv="clr-namespace:TINK.View"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
mc:Ignorable="d"
x:Class="TINK.View.Bike.BCBike">
<ContentView>
<ContentView.Resources>
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
</ContentView.Resources>
<StackLayout
Padding="10">
<Label
FontAttributes="Bold"
Text="{Binding Name}"/>
<Label
Text="{Binding StateText}"
TextColor="{Binding StateColor}"/>
<Label
Text="{Binding ErrorText}"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>
<Button
Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}"
IsEnabled="{Binding IsIdle}"
Command="{Binding OnButtonClicked}"/>
<Grid
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Text=
"{Binding TariffDescription.Header}"
Grid.ColumnSpan="3"
FontAttributes="Bold"/>
<Label
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionFreeTimePerSession}"
IsVisible="{Binding TariffDescription.FreeTimePerSession, Converter={StaticResource Label_Converter}}"
Grid.Row="1"/>
<Label
Text="{Binding TariffDescription.FreeTimePerSession}"
IsVisible="{Binding TariffDescription.FreeTimePerSession, Converter={StaticResource Label_Converter}}"
Grid.Row="1"
Grid.Column="1"/>
<Label
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionFeeEuroPerHour}"
IsVisible="{Binding TariffDescription.FeeEuroPerHour, Converter={StaticResource Label_Converter}}"
Grid.Row="2"/>
<Label
Text="{Binding TariffDescription.FeeEuroPerHour}"
IsVisible="{Binding TariffDescription.FeeEuroPerHour, Converter={StaticResource Label_Converter}}"
Grid.Row="2"
Grid.Column="1"/>
<Label
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionMaxFeeEuroPerDay}"
IsVisible="{Binding TariffDescription.MaxFeeEuroPerDay, Converter={StaticResource Label_Converter}}"
Grid.Row="3"/>
<Label
Text="{Binding TariffDescription.MaxFeeEuroPerDay}"
IsVisible="{Binding TariffDescription.MaxFeeEuroPerDay, Converter={StaticResource Label_Converter}}"
Grid.Row="3"
Grid.Column="1"/>
<Label
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionAboEuroPerMonth}"
IsVisible="{Binding TariffDescription.AboEuroPerMonth, Converter={StaticResource Label_Converter}}"
Grid.Row="4"/>
<Label
Text="{Binding TariffDescription.AboEuroPerMonth}"
IsVisible="{Binding TariffDescription.AboEuroPerMonth, Converter={StaticResource Label_Converter}}"
Grid.Row="4"
Grid.Column="1"/>
</Grid>
</StackLayout>
</ContentView>
</ViewCell>

View file

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Bike
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class BCBike : ViewCell
{
public BCBike()
{
InitializeComponent();
}
}
}

View file

@ -0,0 +1,26 @@
using Xamarin.Forms;
namespace TINK.View.Bike
{
/// <summary>
/// Selects different templates for different bike types (BordComputer bikes, iLockIt bikes).
/// </summary>
public class BikeViewCellTemplateSelector : DataTemplateSelector
{
DataTemplate bCBike;
DataTemplate iLockIBike;
public BikeViewCellTemplateSelector()
{
bCBike = new DataTemplate(typeof(BCBike));
iLockIBike = new DataTemplate(typeof(ILockItBike));
}
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return item is TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel
? iLockIBike
: bCBike;
}
}
}

View file

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:conv="clr-namespace:TINK.View"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
mc:Ignorable="d"
x:Class="TINK.View.Bike.ILockItBike">
<ContentView>
<ContentView.Resources>
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
</ContentView.Resources>
<StackLayout
Padding="10">
<Label
FontAttributes="Bold"
FontSize="Large"
HorizontalTextAlignment="Center"
Text="{Binding Name}"/>
<Label
FontAttributes="Bold"
HorizontalTextAlignment="Center"
IsVisible="{Binding DisplayId, Converter={StaticResource Label_Converter}}"
Text="{Binding DisplayId}"/>
<Label
Text="{Binding StateText}"
TextColor="{Binding StateColor}"/>
<Label
Text="{Binding ErrorText}"
IsVisible="{Binding ErrorText, Converter={StaticResource Label_Converter}}"
TextColor="Red"/>
<Button
Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}"
IsEnabled="{Binding IsIdle}"
Command="{Binding OnButtonClicked}"/>
<Button
Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}"
IsEnabled="{Binding IsIdle}"
Command="{Binding OnLockitButtonClicked}"/>
<Grid
IsVisible="{Binding TariffDescription.Header, Converter={StaticResource Label_Converter}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Text=
"{Binding TariffDescription.Header}"
Grid.ColumnSpan="3"
FontAttributes="Bold"/>
<Label
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionFreeTimePerSession}"
IsVisible="{Binding TariffDescription.FreeTimePerSession, Converter={StaticResource Label_Converter}}"
Grid.Row="1"/>
<Label
Text="{Binding TariffDescription.FreeTimePerSession}"
IsVisible="{Binding TariffDescription.FreeTimePerSession, Converter={StaticResource Label_Converter}}"
Grid.Row="1"
Grid.Column="1"/>
<Label
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionFeeEuroPerHour}"
IsVisible="{Binding TariffDescription.FeeEuroPerHour, Converter={StaticResource Label_Converter}}"
Grid.Row="2"/>
<Label
Text="{Binding TariffDescription.FeeEuroPerHour}"
IsVisible="{Binding TariffDescription.FeeEuroPerHour, Converter={StaticResource Label_Converter}}"
Grid.Row="2"
Grid.Column="1"/>
<Label
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionMaxFeeEuroPerDay}"
IsVisible="{Binding TariffDescription.MaxFeeEuroPerDay, Converter={StaticResource Label_Converter}}"
Grid.Row="3"/>
<Label
Text="{Binding TariffDescription.MaxFeeEuroPerDay}"
IsVisible="{Binding TariffDescription.MaxFeeEuroPerDay, Converter={StaticResource Label_Converter}}"
Grid.Row="3"
Grid.Column="1"/>
<Label
Text="{x:Static resources:AppResources.MessageBikesManagementTariffDescriptionAboEuroPerMonth}"
IsVisible="{Binding TariffDescription.AboEuroPerMonth, Converter={StaticResource Label_Converter}}"
Grid.Row="4"/>
<Label
Text="{Binding TariffDescription.AboEuroPerMonth}"
IsVisible="{Binding TariffDescription.AboEuroPerMonth, Converter={StaticResource Label_Converter}}"
Grid.Row="4"
Grid.Column="1"/>
</Grid>
</StackLayout>
</ContentView>
</ViewCell>

View file

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TINK.Model.Bikes.Bike.BluetoothLock;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Bike
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ILockItBike : ViewCell
{
public ILockItBike()
{
InitializeComponent();
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (Device.RuntimePlatform != Device.iOS)
// Update of size is only required for iOS.
return;
var viewModel = BindingContext as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
if (viewModel == null)
return;
viewModel.PropertyChanged += (sender, e) =>
{
if (e.PropertyName == nameof(TINK.ViewModel.Bikes.Bike.BC.RequestHandler.Base<IBikeInfoMutable>.IsButtonVisible)
|| e.PropertyName == nameof(TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler.Base.IsLockitButtonVisible))
{
// Force update of view cell on iOS.
// https://hausource.visualstudio.com/TINK/_workitems/edit/132
ForceUpdateSize();
}
};
}
}
}

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.BikesAtStation.BikesAtStationPage"
xmlns:local_bike="clr-namespace:TINK.View.Bike"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
Title="{Binding Title}">
<ContentPage.Resources>
<ResourceDictionary>
<local_bike:BikeViewCellTemplateSelector x:Key="bikeTemplateSelector"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<Frame>
<StackLayout
Orientation="Vertical">
<Label
HorizontalOptions="Center"
FontAttributes="Bold"
Text="{Binding StationDetailText}"/>
<ListView
x:Name="BikesAtStationListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/>
<Label
IsVisible="{Binding IsNoBikesAtStationVisible}"
VerticalOptions="EndAndExpand"
Text="{Binding NoBikesAtStationText}"/>
<Label
TextType="Html"
Text="{Binding ContactSupportHintText}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding ContactSupportClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
<Label
IsVisible="{Binding IsLoginRequiredHintVisible}"
TextType="Html"
Text="{Binding LoginRequiredHintText}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding LoginRequiredHintClickedCommand}"/>
</Label.GestureRecognizers>
</Label>
<StackLayout
VerticalOptions="EndAndExpand"
Orientation="Horizontal">
<Label
HeightRequest="20"
Text="{Binding StatusInfoText}"
VerticalOptions="Center"
HorizontalOptions="FillAndExpand"/>
<ActivityIndicator IsRunning="{Binding IsRunning}"
IsVisible="{Binding IsRunning}"
HeightRequest="20"
VerticalOptions="CenterAndExpand"
HorizontalOptions="End">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
</ActivityIndicator.WidthRequest>
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color"
iOS="#2499CE" WinPhone="#2499CE" />
</ActivityIndicator.Color>
</ActivityIndicator>
</StackLayout>
</StackLayout>
</Frame>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,234 @@

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using TINK.Model.Bike.BluetoothLock;
namespace TINK.View.BikesAtStation
{
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using TINK.Model;
using TINK.Services.BluetoothLock.Tdo;
using System.Collections.Generic;
using Serilog;
using TINK.Services.BluetoothLock;
using Plugin.BLE;
using TINK.ViewModel.BikesAtStation;
using TINK.ViewModel.Bikes;
using Xamarin.CommunityToolkit.Extensions;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class BikesAtStationPage : ContentPage, IViewService, IDetailPage
#else
public partial class BikesAtStationPage : ContentPage, IViewService
#endif
{
private BikesAtStationPageViewModel m_oViewModel;
#if TRYNOTBACKSTYLE
public BikesAtStationPage()
{
InitializeComponent();
var l_oModel = App.ModelRoot;
var l_oViewModel = new BikesAtStationPageViewModel(
l_oModel.BikesAtStation,
l_oModel.ActiveUser,
l_oModel.SelectedStation,
this);
BindingContext = l_oViewModel;
BikesAtStationListView.ItemsSource = l_oViewModel;
}
#else
public BikesAtStationPage()
{
}
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
protected async override void OnAppearing()
{
if (m_oViewModel != null)
{
#if BACKSTYLE
// Hide master- detail menu to force user to navigate using back button.
m_oNavigation.IsGestureEnabled = false;
#endif
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
return;
}
try
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new BikesAtStationPageViewModel(
model.ActiveUser,
App.PermissionsService,
App.BluetoothService,
Device.RuntimePlatform,
model.SelectedStation,
() => model.GetIsConnected(),
(isConnected) => model.GetConnector(isConnected),
App.GeolocationServicesContainer.Active,
model.LocksServices.Active,
model.Polling,
(url) => DependencyService.Get<IExternalBrowserService>().OpenUrl(url),
(d, obj) => synchronizationContext.Post(d, obj),
model.SmartDevice,
this)
{
IsReportLevelVerbose = model.IsReportLevelVerbose
};
}
catch (Exception exception)
{
Log.ForContext<BikesAtStationPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
return;
}
InitializeComponent();
#if BACKSTYLE
// Hide master- detail menu to force user to navigate using back button.
m_oNavigation.IsGestureEnabled = false;
#endif
BindingContext = m_oViewModel;
BikesAtStationListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
}
/// <summary>
/// Invoked when pages is closed/ hidden.
/// Stops update process.
/// </summary>
protected async override void OnDisappearing()
{
if (m_oViewModel != null)
{
// View model might be null.
await m_oViewModel?.OnDisappearing();
}
#if BACKSTYLE
if (m_oNavigation!= null)
m_oNavigation.IsGestureEnabled = true; // Enables master- detail menu navigation again when page is unloaded.
#endif
}
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="cancel">Type of buttons.</param>
public new async Task DisplayAlert(string title, string message, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
#if USEFLYOUT
/// <summary> Creates and a page an shows it.</summary>
/// <remarks> When user is not logged in navigation to Login page is supported.</remarks>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string title = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>
public async Task PushModalAsync(ViewTypes typeOfPage)
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync()
{
throw new NotSupportedException();
}
public Task PushAsync(ViewTypes p_oTypeOfPage)
{
throw new NotImplementedException();
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#else
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#endif
}
}

View file

@ -0,0 +1,19 @@
using System;
using System.Globalization;
using Xamarin.Forms;
namespace TINK.View
{
/// <summary> Inverts a bool.</summary>
public class BoolInverterConverter : IValueConverter
{
/// <summary> Inverts a bool.</summary>
/// <param name="value">Bool to invert.</param>
/// <returns>Inverted bool.</returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> value is bool flag && !flag;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> value is bool flag && !flag;
}
}

View file

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:conv="clr-namespace:TINK.View"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="TINK.View.Contact.ContactPage"
Title="{x:Static resources:AppResources.MarkingContactPageTitle}">
<ContentPage.Resources>
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="StringNotNullOrEmpty_Converter"/>
<conv:BoolInverterConverter x:Key="BoolInvert_Converter"/>
</ContentPage.Resources>
<ContentPage.Content>
<ScrollView>
<Frame>
<StackLayout x:Name="ContactPageView">
<Frame
IsVisible="{Binding
Path=IsOperatorInfoAvaliable,
Converter={StaticResource BoolInvert_Converter}}">
<!-- Button to select station and explanation text -->
<StackLayout>
<Label
TextType="Html"
Text="{x:Static resources:AppResources.MarkingContactNoStationInfoAvailableNoButton}"/>
<Button
Text="{x:Static resources:AppResources.ActionSelectStation}"
Command="{Binding OnSelectStationRequest}"/>
</StackLayout>
</Frame>
<Frame
IsVisible="{Binding IsOperatorInfoAvaliable}">
<!-- Operator info -->
<StackLayout>
<Label
IsVisible="{Binding IsOperatorInfoAvaliable}"
HorizontalOptions="Center"
FontAttributes="Bold"
Text="{Binding ProviderNameText}"/>
<!--- Mail address -->
<Label
IsVisible="{Binding MailAddressText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
FormattedText="{Binding MailAddressAndMotivationsText}"/>
<Button
x:Name="MailAddressButton"
IsVisible="{Binding MailAddressText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
Text="{Binding MailAddressText}"
IsEnabled="{Binding IsSendMailAvailable}"
Command="{Binding OnMailRequest}"/>
<!--- Mail address -->
<Label
IsVisible="{Binding PhoneNumberText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
FormattedText="{Binding PhoneContactText}"/>
<Button
x:Name="PhoneNumberButton"
IsVisible="{Binding PhoneNumberText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
Text="{Binding PhoneNumberText}"
IsEnabled="{Binding IsDoPhoncallAvailable}"
Command="{Binding OnPhoneRequest}"/>
</StackLayout>
</Frame>
<Frame>
<StackLayout>
<Label FormattedText="{Binding LikeTinkApp}"/>
<Button Text="{x:Static resources:AppResources.ActionContactRate}"
Command="{Binding OnRateRequest}"/>
</StackLayout>
</Frame>
</StackLayout>
</Frame>
</ScrollView>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,102 @@
using System;
using System.Threading.Tasks;
using TINK.Model.Device;
using TINK.View.MasterDetail;
using TINK.ViewModel.Info;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Contact
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ContactPage : ContentPage, IViewService, IDetailPage
{
public ContactPage ()
{
InitializeComponent ();
ContactPageView.BindingContext = new ContactPageViewModel(
App.ModelRoot.SelectedStation,
App.ModelRoot.Uris.ActiveUri,
() => App.CreateAttachment(),
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
this);
}
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string title = null)
=> NavigationMasterDetail.ShowPage(p_oType.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
{
throw new NotSupportedException();
}
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync()
{
throw new NotSupportedException();
}
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
if (!(Activator.CreateInstance(typeOfPage.GetViewType()) is IDetailPage detailPage))
{
await Task.CompletedTask;
return;
}
// Set reference to navigation object to be able to show page on newly shown detailPage.
detailPage.NavigationMasterDetail = NavigationMasterDetail;
await Navigation.PushAsync((Page)detailPage);
}
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail { set; private get; }
#endif
}
}

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:maps="clr-namespace:Xamarin.Forms.GoogleMaps;assembly=Xamarin.Forms.GoogleMaps"
xmlns:bindings="clr-namespace:Xamarin.Forms.GoogleMaps.Bindings;assembly=Xamarin.Forms.GoogleMaps.Bindings"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="TINK.View.Contact.SelectStationPage"
Title="{x:Static resources:AppResources.MarkingSelectStationPage}">
<ContentPage.Content>
<StackLayout>
<Grid
IsEnabled="{Binding IsMapPageEnabled}"
VerticalOptions="FillAndExpand">
<maps:Map WidthRequest="320" HeightRequest="800"
x:Name="MyMap"
IsShowingUser="False"
MapType="Street">
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>
<bindings:PinClickedToCommandBehavior Command="{Binding PinClickedCommand}"/>
</maps:Map.Behaviors>
</maps:Map>
</Grid>
<StackLayout
Margin="6,3,6,6"
VerticalOptions="EndAndExpand"
Orientation="Horizontal">
<Label
HeightRequest="20"
Text="{Binding StatusInfoText}"
VerticalOptions="Center"
HorizontalOptions="FillAndExpand"/>
<ActivityIndicator IsRunning="{Binding IsRunning}"
IsVisible="{Binding IsRunning}"
HeightRequest="20"
VerticalOptions="CenterAndExpand"
HorizontalOptions="End">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
</ActivityIndicator.WidthRequest>
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color"
iOS="#2499CE" WinPhone="#2499CE" />
</ActivityIndicator.Color>
</ActivityIndicator>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,207 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Contact
{
using Serilog;
using TINK.ViewModel.Contact;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class SelectStationPage : ContentPage, IViewService, IDetailPage
#else
public partial class SelectStationPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify about whether page appears or hides. </summary>
private SelectStationPageViewModel SelectStationPageViewModel { get; set; }
public SelectStationPage()
{
InitializeComponent();
}
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="cancel">Type of buttons.</param>
public new async Task DisplayAlert(string title, string message, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="type">Type of page to show.</param>
public void ShowPage(ViewTypes type, string title = null)
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Type of page to display.</param>
public async Task PushModalAsync(ViewTypes typeOfPage)
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
/// <summary> Pops a page from the modal stack. </summary>
public async Task PopModalAsync()
=> await Navigation.PopModalAsync();
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(typeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary> Delegate to perform navigation.</summary>
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
protected async override void OnAppearing()
{
// Pass reference to member Navigation to show bikes at station x dialog.
try
{
Log.ForContext<SelectStationPageViewModel>().Verbose("Constructing select station view model.");
#if TRYNOTBACKSTYLE
SelectStationPageViewModel = new SelectStationPageViewModel();
#else
SelectStationPageViewModel = new SelectStationPageViewModel(
App.ModelRoot,
App.PermissionsService,
App.BluetoothService,
App.GeolocationServicesContainer.Active,
(mapspan) => MyMap.MoveToRegion(mapspan),
this,
Navigation);
#endif
}
catch (Exception exception)
{
Log.ForContext<SelectStationPageViewModel>().Error("Constructing select station view model failed. {Exception}", exception);
return;
}
try
{
BindingContext = SelectStationPageViewModel;
#if USEFLYOUT
SelectStationPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
#endif
}
catch (Exception exception)
{
Log.ForContext<SelectStationPageViewModel>().Error("Setting binding/ navigaton on select station failed. {Exception}", exception);
return;
}
try
{
base.OnAppearing();
}
catch (Exception exception)
{
// Continue because styling is not essential.
Log.ForContext<SelectStationPageViewModel>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
return;
}
try
{
// Pre move and scanle maps to avoid initial display of map in Rome.
Log.ForContext<SelectStationPageViewModel>().Verbose("Moving and scaling map.");
SelectStationPageViewModel.MoveAndScale(
(mapSpan) => MyMap.MoveToRegion(mapSpan),
App.ModelRoot.Uris.ActiveUri);
}
catch (Exception exception)
{
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
Log.ForContext<SelectStationPageViewModel>().Error("Moving and scaling map failed. {Exception}", exception);
}
try
{
Log.ForContext<SelectStationPageViewModel>().Verbose("Invoking OnAppearing on select station view model.");
await SelectStationPageViewModel.OnAppearing();
}
catch (Exception exception)
{
Log.ForContext<SelectStationPageViewModel>().Error("Invoking OnAppearing on select station view model failed. {Exception}", exception);
return;
}
}
}
}

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.CopriWebView.ManageAccountPage">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackLayout>
<WebView x:Name="ManageAccount"
HeightRequest="1400"
WidthRequest="1000"
Source="{Binding Uri}" />
</StackLayout>
</Grid>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,42 @@
using TINK.Model.Device;
using TINK.ViewModel.Login;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.CopriWebView
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ManageAccountPage : ContentPage
{
public ManageAccountPage ()
{
InitializeComponent ();
ManageAccount.Navigating += (sender, ev) =>
{
if (!ev.Url.ToUpper().EndsWith(".PDF"))
{
// Stay inside web view except for downloading pdf- files.
return;
}
DependencyService.Get<IExternalBrowserService>().OpenUrl(ev.Url);
};
ManageAccount.Navigated += (sender, ev) =>
{
if (ev.Result == WebNavigationResult.Success) return;
ManageAccount.Source = new HtmlWebViewSource
{
Html = "<html><b>Kann persönliche Daten nicht anzeigen/ verwalten!</b><br>Verbindung mit Internet ok?</html>"
};
};
ManageAccount.BindingContext = new ManageAccountViewModel(
App.ModelRoot.ActiveUser.SessionCookie,
Model.TinkApp.MerchantId,
App.ModelRoot.NextActiveUri.Host);
}
}
}

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.CopriWebView.PasswordForgottenPage">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackLayout>
<WebView x:Name="PasswordForgottenWebView"
HeightRequest="1400"
WidthRequest="1000"
Source="{Binding Uri}" />
</StackLayout>
</Grid>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,30 @@

using TINK.ViewModel.CopriWebView;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.CopriWebView
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PasswordForgottenPage : ContentPage
{
public PasswordForgottenPage ()
{
InitializeComponent ();
PasswordForgottenWebView.Navigated += (sender, ev) =>
{
if (ev.Result == WebNavigationResult.Success) return;
PasswordForgottenWebView.Source = new HtmlWebViewSource
{
Html = "<html><b>Kann Passwort vergessen Seite nicht anzeigen!</b><br>Verbindung mit Internet ok?</html>"
};
};
PasswordForgottenWebView.BindingContext = new PasswordForgottonViewModel(
Model.TinkApp.MerchantId,
App.ModelRoot.NextActiveUri.Host);
}
}
}

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.CopriWebView.RegisterPage">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackLayout>
<WebView x:Name="RegisterView"
HeightRequest="1400"
WidthRequest="1000"
Source="{Binding Uri}" />
</StackLayout>
</Grid>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,33 @@

using TINK.Model.Device;
using TINK.ViewModel.CopriWebView;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.CopriWebView
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RegisterPage : ContentPage
{
public RegisterPage()
{
DependencyService.Get<IWebView>().ClearCookies();
InitializeComponent();
RegisterView.Navigated += (sender, ev) =>
{
if (ev.Result == WebNavigationResult.Success) return;
RegisterView.Source = new HtmlWebViewSource
{
Html = "<html><b>Kann Anmeldeseite nicht anzeigen</b>!<br>Verbindung mit Internet ok?</html>"
};
};
RegisterView.BindingContext = new RegisterPageViewModel(
App.ModelRoot.NextActiveUri.Host);
}
}
}

View file

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8" ?>
<xct:Popup xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:local="clr-namespace:TINK.View"
x:TypeArguments="local:FeedbackPopup+Result"
x:Class="TINK.View.FeedbackPopup">
<xct:Popup.Resources>
<x:String x:Key="check_circle">&#xf058;</x:String>
</xct:Popup.Resources>
<Grid>
<Grid.RowDefinitions>
<!-- Head and title row -->
<RowDefinition Height="auto"/>
<!--- checkbox and input elements-->
<RowDefinition Height="*"/>
<!--- ok button-->
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid
Padding="30"
BackgroundColor="{DynamicResource primary-back-title-color}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label
HorizontalTextAlignment="Center"
FontSize="Large"
Text="Fahrrad erfolgreich zurückgegeben!"/>
<Image Grid.Row="1">
<Image.Source>
<FontImageSource Size="Header" Glyph="{StaticResource check_circle}" FontFamily="FA-S"/>
</Image.Source>
</Image>
</Grid>
<ScrollView Grid.Row="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout
Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox x:Name="brockenCheckBox" IsChecked="True"/>
<Label
Grid.Column="1"
FontSize="Medium"
Text="Rad ist in Ordnung"/>
</Grid>
<Editor
Grid.Row="1"
x:Name="feedbackMessage"
AutoSize="TextChanges"
Placeholder="Bei Bedarf bitte hier Rückmeldung eingeben."
Text="">
<Editor.Triggers>
<DataTrigger TargetType="Editor"
Binding="{Binding Source={x:Reference brockenCheckBox}, Path=IsChecked}"
Value="true">
<Setter Property="Placeholder"
Value="Bei Bedarf bitte hier Rückmeldung eingeben." />
</DataTrigger>
<DataTrigger TargetType="Editor"
Binding="{Binding Source={x:Reference brockenCheckBox}, Path=IsChecked}"
Value="false">
<Setter Property="Placeholder"
Value="Bitte Zustand/ Defekt hier beschreiben." />
</DataTrigger>
</Editor.Triggers>
</Editor>
</StackLayout>
</Grid>
</ScrollView>
<Button
Grid.Row="2"
Clicked="OnOkClicked"
Text="OK"/>
</Grid>
</xct:Popup>

View file

@ -0,0 +1,58 @@
using System;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms.Xaml;
namespace TINK.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FeedbackPopup : Popup<FeedbackPopup.Result>
{
public FeedbackPopup()
{
InitializeComponent();
}
protected override FeedbackPopup.Result GetLightDismissResult()
{
return new Result
{
Message = feedbackMessage.Text,
IsBikeBroken = brockenCheckBox.IsChecked
};
}
private void OnOkClicked(object sender, EventArgs eventArgs)
{
var result = new Result
{
Message = feedbackMessage.Text,
IsBikeBroken = brockenCheckBox.IsChecked
};
Dismiss(result);
}
/// <summary>
/// Feedback given by user when returning bike.
/// </summary>
#if USCSHARP9
public class Result : IViewService.IUserFeedback
#else
public new class Result : IUserFeedback
#endif
{
/// <summary>
/// Holds whether bike is broken or not.
/// </summary>
public bool IsBikeBroken { get; set; }
/// <summary>
/// Holds either
/// - general feedback
/// - error description of broken bike
/// or both.
/// </summary>
public string Message { get; set; }
}
}
}

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="TINK.View.Contact.FeesAndBikesPage">
<!--Pages can be added as references or inline-->
<ContentPage Title="{x:Static resources:AppResources.MarkingTabFees}">
<ContentPage.Content>
<StackLayout>
<WebView
x:Name="InfoRentBikeWebView"
HeightRequest="1000"
WidthRequest="1000"
Source="{Binding RentBikeText}"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
<ContentPage Title="{x:Static resources:AppResources.MarkingTabBikes}">
<ContentPage.Content>
<StackLayout>
<WebView
x:Name="InfoTypesOfBikesWebView"
HeightRequest="1000"
WidthRequest="1000"
Source="{Binding TypesOfBikesText}"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
</TabbedPage>

View file

@ -0,0 +1,37 @@
using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using TINK.ViewModel.Contact;
namespace TINK.View.Contact
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FeesAndBikesPage : TabbedPage
{
public HelpContactViewModel ViewModel { get; }
public FeesAndBikesPage ()
{
InitializeComponent();
ViewModel = new HelpContactViewModel(
App.ModelRoot.NextActiveUri.Host,
App.ModelRoot.IsSiteCachingOn,
resourceName => ViewModelResourceHelper.GetSource(resourceName));
BindingContext = ViewModel;
/// Info about renting.
InfoRentBikeWebView.Navigating += ViewModelHelper.OnNavigating;
/// Info about types of bikes.
InfoTypesOfBikesWebView.Navigating += ViewModelHelper.OnNavigating;
}
/// <summary> Called when page is shown. </summary>
protected override void OnAppearing()
{
ViewModel.OnAppearing();
}
}
}

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.FindBike.FindBikePage"
xmlns:local_bike="clr-namespace:TINK.View.Bike">
<ContentPage.Resources>
<ResourceDictionary>
<local_bike:BikeViewCellTemplateSelector x:Key="bikeTemplateSelector"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<Frame>
<StackLayout>
<Entry
Placeholder="Fahrrad-Nummer bitte hier eingeben"
IsVisible="{Binding IsSelectBikeVisible}"
MaxLength="10"
CursorPosition="0"
Text="{Binding BikeIdUserInput}">
</Entry>
<Button
Text="Rad Wählen"
IsEnabled="{Binding IsSelectBikeEnabled}"
IsVisible="{Binding IsSelectBikeVisible}"
Command="{Binding OnSelectBikeRequest}">
</Button>
<ListView
x:Name="FindBikeListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/>
<StackLayout
VerticalOptions="EndAndExpand"
Orientation="Horizontal">
<Label
HeightRequest="20"
Text="{Binding StatusInfoText}"
VerticalOptions="Center"
HorizontalOptions="FillAndExpand"/>
<ActivityIndicator IsRunning="{Binding IsRunning}"
IsVisible="{Binding IsRunning}"
HeightRequest="20"
VerticalOptions="CenterAndExpand"
HorizontalOptions="End">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
</ActivityIndicator.WidthRequest>
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color"
iOS="#2499CE" WinPhone="#2499CE" />
</ActivityIndicator.Color>
</ActivityIndicator>
</StackLayout>
</StackLayout>
</Frame>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,144 @@
using Serilog;
using System;
using System.Threading;
using System.Threading.Tasks;
using TINK.ViewModel.FindBike;
using Xamarin.CommunityToolkit.Extensions;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.FindBike
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FindBikePage : ContentPage, IViewService
{
/// <summary> Refernce to view model. </summary>
FindBikePageViewModel m_oViewModel = null;
public FindBikePage () { }
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
protected async override void OnAppearing()
{
if (m_oViewModel != null)
{
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
return;
}
try
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new FindBikePageViewModel(
model.ActiveUser,
App.PermissionsService,
App.BluetoothService,
Device.RuntimePlatform,
() => model.GetIsConnected(),
(isConnected) => model.GetConnector(isConnected),
App.GeolocationServicesContainer.Active,
model.LocksServices.Active,
model.Polling,
(d, obj) => synchronizationContext.Post(d, obj),
model.SmartDevice,
this)
{
IsReportLevelVerbose = model.IsReportLevelVerbose
};
}
catch (Exception exception)
{
Log.ForContext<FindBikePage>().Error("Displaying bikes at station page failed. {Exception}", exception);
await DisplayAlert("Fehler", $"Seite Fahrrad Wählen kann nicht angezeigt werden. ${exception.Message}", "OK");
return;
}
InitializeComponent();
BindingContext = m_oViewModel;
FindBikeListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
}
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strCancel">Type of buttons.</param>
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strAccept">Text of accept button.</param>
/// <param name="p_strCancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>
public async Task PushModalAsync(ViewTypes typeOfPage)
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync() => throw new NotSupportedException();
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
#if USCSHARP9
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#else
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#endif
}
}

View file

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.Info.BikeInfo.BikeInfoCarouselPage">
<CarouselPage.ItemTemplate>
<DataTemplate>
<ContentPage>
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0,40,0,0" />
</OnPlatform>
</ContentPage.Padding>
<ScrollView Orientation="Vertical">
<StackLayout>
<Label
Text="{Binding Title}"
FontSize="Medium"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
VerticalOptions="EndAndExpand"
VerticalTextAlignment="End"/>
<Image
IsVisible="{Binding IsImageVisble}"
Source="{Binding Image}"
Aspect="AspectFit"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
<Label
Text="{Binding DescriptionText}"
HorizontalOptions="Center"
HorizontalTextAlignment="Center"
VerticalOptions="StartAndExpand"
VerticalTextAlignment="Start"/>
<Button
Text="Schließen"
IsVisible="{Binding IsCloseVisible}"
Command="{Binding OnCloseRequest}"
VerticalOptions="End"/>
<ProgressBar
VerticalOptions="End"
Progress="{Binding ProgressValue}"/>
</StackLayout>
</ScrollView>
</ContentPage>
</DataTemplate>
</CarouselPage.ItemTemplate>
</CarouselPage>

View file

@ -0,0 +1,128 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using TINK.ViewModel.Info.BikeInfo;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Info.BikeInfo
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class BikeInfoCarouselPage : CarouselPage, IViewService, IDetailPage
#else
public partial class BikeInfoCarouselPage : CarouselPage, IViewService
#endif
{
public BikeInfoCarouselPage ()
{
InitializeComponent ();
ItemsSource = new BikeInfoViewModel(
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.RessourcePrefix}Images.{resourceName}"),
this).CarouselItems;
}
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strCancel">Type of buttons.</param>
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strAccept">Text of accept button.</param>
/// <param name="p_strCancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
{
return await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
}
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushModalAsync(ViewTypes p_oTypeOfPage)
{
throw new NotSupportedException();
}
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync()
{
throw new NotSupportedException();
}
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushAsync(ViewTypes p_oTypeOfPage)
{
throw new NotImplementedException();
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#endif
}
}

View file

@ -0,0 +1,40 @@
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class InfoPage : ContentPage
{
public InfoPage ()
{
InitializeComponent ();
#if __IOS__
var resourcePrefix = "TINK.iOS.";
#endif
#if __ANDROID__
var resourcePrefix = "TINK.Droid.";
#endif
#if WINDOWS_PHONE
var resourcePrefix = "TINK.WinPhone.";
#endif
Debug.WriteLine("Using this resource prefix: " + resourcePrefix);
// note that the prefix includes the trailing period '.' that is required
var assembly = typeof(InfoPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream
(resourcePrefix + "HtmlResouces.Info.html");
var l_oHtmlViewSource = new HtmlWebViewSource
{
Html = (new StreamReader(stream, Encoding.UTF8)).ReadToEnd()
};
InfoWebView.Source = l_oHtmlViewSource;
}
}
}

View file

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Info
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class InfoPage : ContentPage
{
public InfoPage ()
{
InitializeComponent ();
}
}
}

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.Info.TabbedPageInfo"
x:Name="TabbedInfoPage">
<!--Pages can be added as references or inline-->
<ContentPage Title="App">
<ContentPage.Content>
<StackLayout>
<WebView
x:Name="InfoLicenses"
Source="{Binding InfoLicenses}"
HeightRequest="1000"
WidthRequest="1000" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
<ContentPage Title="Datenschutz">
<ContentPage.Content>
<StackLayout>
<WebView
x:Name="InfoDatenschutz"
Source="{Binding InfoPrivacy}"
HeightRequest="1000"
WidthRequest="1000" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
<ContentPage Title="AGB">
<ContentPage.Content>
<StackLayout>
<WebView
x:Name="InfoABG"
Source ="{Binding InfoAgb}"
HeightRequest="1000"
WidthRequest="1000" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
<ContentPage Title="Impressum">
<ContentPage.Content>
<StackLayout>
<WebView
x:Name="InfoImpressum"
Source="{Binding InfoImpressum}"
HeightRequest="1000"
WidthRequest="1000" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
</TabbedPage>

View file

@ -0,0 +1,36 @@
using TINK.ViewModel;
using TINK.ViewModel.Info;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Info
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TabbedPageInfo : TabbedPage
{
public InfoViewModel ViewModel { get; }
public TabbedPageInfo()
{
InitializeComponent();
ViewModel = new InfoViewModel(
App.ModelRoot.NextActiveUri.Host,
App.ModelRoot.IsSiteCachingOn,
resourceName => ViewModelResourceHelper.GetSource(resourceName));
TabbedInfoPage.BindingContext = ViewModel;
InfoLicenses.Navigating += ViewModelHelper.OnNavigating;
InfoDatenschutz.Navigating += ViewModelHelper.OnNavigating;
InfoABG.Navigating += ViewModelHelper.OnNavigating;
InfoImpressum.Navigating += ViewModelHelper.OnNavigating;
}
/// <summary> Called when page is shown. </summary>
protected override void OnAppearing()
{
ViewModel.OnAppearing();
}
}
}

View file

@ -0,0 +1,35 @@
using System.Windows.Input;
using Xamarin.Forms;
namespace TINK.View
{
public static class ListViewAttachedBehavior
{
public static readonly BindableProperty CommandProperty =
BindableProperty.CreateAttached(
"Command",
typeof(ICommand),
typeof(ListViewAttachedBehavior),
null,
propertyChanged: OnCommandChanged);
static void OnCommandChanged(BindableObject view, object oldValue, object newValue)
{
var entry = view as ListView;
if (entry == null)
return;
entry.ItemTapped += (sender, e) =>
{
var command = (newValue as ICommand);
if (command == null)
return;
if (command.CanExecute(e.Item))
{
command.Execute(e.Item);
}
};
}
}
}

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="TINK.View.Login.LoginPage">
<ScrollView>
<Frame>
<StackLayout x:Name="LoginPageView">
<Frame>
<StackLayout>
<Label Text="{x:Static resources:AppResources.MarkingLoginEmailAddressLabel}"/>
<Entry
Placeholder="{x:Static resources:AppResources.MarkingLoginEmailAddressPlaceholder}"
Keyboard="Email"
AutomationId="mail_address_text"
x:Name="EMailEntry"
Text="{Binding MailAddress}"
IsEnabled="{Binding IsLoggedOut}"/>
<Label Text="{x:Static resources:AppResources.MarkingLoginPasswordLabel}"/>
<Entry
Placeholder="{x:Static resources:AppResources.MarkingLoginPasswordPlaceholder}"
AutomationId="password_text"
IsPassword="true"
x:Name="PasswordEntry"
Text="{Binding Password}"
IsEnabled="{Binding IsLoggedOut}"/>
<Button
Text="{x:Static resources:AppResources.ActionLoginLogin}"
AutomationId="login_button"
Command="{Binding OnLoginRequest}"
IsEnabled="{Binding IsLoginRequestAllowed}">
</Button>
<Button
Text="{x:Static resources:AppResources.ActionLoginRegister}"
AutomationId="register_button"
Command="{Binding OnRegisterRequest}"
IsVisible="{Binding IsWebViewElementsVisible}">
</Button>
<Label
IsVisible="{Binding IsRegisterTargetsInfoVisible}"
FormattedText="{Binding RegisterTargetsInfo}">
</Label>
<Button
Text="{x:Static resources:AppResources.ActionLoginPasswordForgotten}"
AutomationId="password_forgotten_button"
Command="{Binding OnPasswordForgottonRequest}">
</Button>
</StackLayout>
</Frame>
</StackLayout>
</Frame>
</ScrollView>
</ContentPage>

View file

@ -0,0 +1,122 @@
using System;
using System.Threading.Tasks;
using TINK.Model.Device;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.ViewModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Login
{
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class LoginPage : ContentPage, IViewService, IDetailPage
#else
public partial class LoginPage : ContentPage, IViewService
#endif
{
public LoginPage ()
{
InitializeComponent ();
var l_oModel = App.ModelRoot;
#if !BACKSTYLE
var l_oViewModel = new LoginPageViewModel(
l_oModel,
(url) => DependencyService.Get< IExternalBrowserService>().OpenUrl(url),
this);
LoginPageView.BindingContext = l_oViewModel;
#else
LoginPageView.BindingContext = new LoginPageViewModel(l_oModel.ActiveUser, this, Navigation);
#endif
}
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strCancel">Type of buttons.</param>
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> m_oNavigation.ShowPage(p_oType.GetViewType(), p_strTitle);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public async Task PushModalAsync(ViewTypes typeOfPage)
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync()
{
throw new NotSupportedException();
}
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes p_oTypeOfPage)
{
await Navigation.PushAsync((Page)Activator.CreateInstance(p_oTypeOfPage.GetViewType()));
}
#if USEFLYOUT
/// <summary>
/// Delegate to perform navigation.
/// </summary>
private INavigationMasterDetail m_oNavigation;
/// <summary>
/// Delegate to perform navigation.
/// </summary>
public INavigationMasterDetail NavigationMasterDetail
{
set { m_oNavigation = value; }
}
#endif
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#endif
}
}

View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:maps="clr-namespace:Xamarin.Forms.GoogleMaps;assembly=Xamarin.Forms.GoogleMaps"
xmlns:bindings="clr-namespace:Xamarin.Forms.GoogleMaps.Bindings;assembly=Xamarin.Forms.GoogleMaps.Bindings"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="TINK.View.Map.MapPage"
Title="{x:Static resources:AppResources.MarkingMapPage}">
<StackLayout>
<Grid
IsEnabled="{Binding IsMapPageEnabled}"
VerticalOptions="FillAndExpand">
<maps:Map WidthRequest="320" HeightRequest="800"
x:Name="MyMap"
IsShowingUser="False"
MapType="Street">
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}"/>
<bindings:PinClickedToCommandBehavior Command="{Binding PinClickedCommand}"/>
</maps:Map.Behaviors>
</maps:Map>
<Button
x:Name="TINKButton"
AutomationId ="FilterTINK_button"
Text="TINK"
Command="{Binding OnToggleKonradToTink}"
IsVisible="{Binding IsToggleVisible}"
TextColor ="{Binding TinkColor}"
VerticalOptions="Start"
HorizontalOptions="StartAndExpand"
WidthRequest="80">
</Button>
<Button
x:Name="KonradButton"
AutomationId ="FilterKonrad_button"
Text="Konrad"
Command="{Binding OnToggleTinkToKonrad}"
IsVisible="{Binding IsToggleVisible}"
TextColor="{Binding KonradColor}"
VerticalOptions="Start"
HorizontalOptions="EndAndExpand"
WidthRequest="80">
</Button>
</Grid>
<StackLayout
Margin="6,3,6,6"
VerticalOptions="EndAndExpand"
Orientation="Horizontal">
<Label
HeightRequest="20"
Text="{Binding StatusInfoText}"
VerticalOptions="Center"
HorizontalOptions="FillAndExpand"/>
<ActivityIndicator IsRunning="{Binding IsRunning}"
IsVisible="{Binding IsRunning}"
HeightRequest="20"
VerticalOptions="CenterAndExpand"
HorizontalOptions="End">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
</ActivityIndicator.WidthRequest>
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color"
iOS="#2499CE" WinPhone="#2499CE" />
</ActivityIndicator.Color>
</ActivityIndicator>
</StackLayout>
</StackLayout>
</ContentPage>

View file

@ -0,0 +1,243 @@
using System;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Map
{
using Serilog;
using TINK.ViewModel.Map;
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class MapPage : ContentPage, IViewService, IDetailPage
#else
public partial class MapPage : ContentPage, IViewService
#endif
{
/// <summary> View model to notify about whether page appears or hides. </summary>
private MapPageViewModel MapPageViewModel { get; set; }
/// <summary>
/// Constructs map page instance.
/// </summary>
public MapPage()
{
InitializeComponent();
}
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="cancel">Type of buttons.</param>
public new async Task DisplayAlert(string title, string message, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, cancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, message, accept, cancel);
#if USEFLYOUT
/// <summary>
/// Creates and a page an shows it.
/// </summary>
/// <param name="p_oTypeOfPage">Type of page to show.</param>
public void ShowPage(ViewTypes type, string title = null)
=> NavigationMasterDetail.ShowPage(type.GetViewType(), title);
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Type of page to display.</param>
public async Task PushModalAsync(ViewTypes typeOfPage)
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
/// <summary> Pops a page from the modal stack. </summary>
public async Task PopModalAsync()
=> await Navigation.PopModalAsync();
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="typeOfPage">Page to display.</param>
public async Task PushAsync(ViewTypes typeOfPage)
{
#if USEFLYOUT
var page = Activator.CreateInstance(typeOfPage.GetViewType()) as IDetailPage;
#else
var page = Activator.CreateInstance(p_oTypeOfPage.GetViewType());
#endif
if (page == null)
{
return;
}
#if USEFLYOUT
page.NavigationMasterDetail = NavigationMasterDetail;
#endif
await Navigation.PushAsync((Page)page);
}
#if USCSHARP9
public Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#else
public Task<IUserFeedback> DisplayUserFeedbackPopup() => throw new NotSupportedException();
#endif
#if USEFLYOUT
/// <summary> Delegate to perform navigation.</summary>
public INavigationMasterDetail NavigationMasterDetail { private get; set; }
#endif
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
protected async override void OnAppearing()
{
// Pass reference to member Navigation to show bikes at station x dialog.
try
{
Log.ForContext<MapPage>().Verbose("Constructing map page view model.");
#if TRYNOTBACKSTYLE
MapPageViewModel = new MapPageViewModel();
#else
MapPageViewModel = new MapPageViewModel(
App.ModelRoot,
App.PermissionsService,
App.BluetoothService,
App.GeolocationServicesContainer.Active,
(mapspan) => MyMap.MoveToRegion(mapspan),
this,
Navigation);
#endif
} catch (Exception exception)
{
Log.ForContext<MapPage>().Error("Constructing map page view model failed. {Exception}", exception);
return;
}
try
{
BindingContext = MapPageViewModel;
#if USEFLYOUT
MapPageViewModel.NavigationMasterDetail = NavigationMasterDetail;
#endif
}
catch (Exception exception)
{
Log.ForContext<MapPage>().Error("Setting binding/ navigaton on map page failed. {Exception}", exception);
return;
}
try
{
if (Device.RuntimePlatform == Device.iOS)
{
TINKButton.BackgroundColor = Color.LightGray;
TINKButton.BorderColor = Color.Black;
TINKButton.Margin = new Thickness(10, 10, 10, 10);
KonradButton.BackgroundColor = Color.LightGray;
KonradButton.BorderColor = Color.Black;
KonradButton.Margin = new Thickness(10, 10, 10, 10);
}
}
catch (Exception exception)
{
// Continue because styling is not essential.
Log.ForContext<MapPage>().Error("IOS specific styling of map page failed. {Exception}", exception);
}
try
{
base.OnAppearing();
}
catch (Exception exception)
{
// Continue because styling is not essential.
Log.ForContext<MapPage>().Error("Invoking OnAppearing of base failed. {Exception}", exception);
return;
}
try
{
// Pre move and scanle maps to avoid initial display of map in Rome.
Log.ForContext<MapPage>().Verbose("Moving and scaling map.");
MapPageViewModel.MoveAndScale(
(mapSpan) => MyMap.MoveToRegion(mapSpan),
App.ModelRoot.Uris.ActiveUri,
App.ModelRoot.GroupFilterMapPage);
}
catch(Exception exception)
{
// Continue because a map not beeing moved/ scaled is no reason for aborting startup.
Log.ForContext<MapPage>().Error("Moving and scaling map failed. {Exception}", exception);
}
try
{
Log.ForContext<MapPage>().Verbose("Invoking OnAppearing on map page view model.");
await MapPageViewModel.OnAppearing();
}
catch (Exception exception)
{
Log.ForContext<MapPage>().Error("Invoking OnAppearing on map page view model failed. {Exception}", exception);
return;
}
}
/// <summary>
/// Invoked when pages is closed/ hidden.
/// Stops update process.
/// </summary>
protected override async void OnDisappearing()
{
if (MapPageViewModel != null)
{
// View model might be null.
await MapPageViewModel?.OnDisappearing();
}
base.OnDisappearing();
}
}
}

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local_minisurvey="clr-namespace:TINK.View.MiniSurvey.Question"
x:Class="TINK.View.MiniSurvey.MiniSurveyPage">
<ContentPage.Resources>
<ResourceDictionary>
<local_minisurvey:QuestionViewCellTemplateSelector x:Key="questionViewCellTemplateSelector"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<Frame>
<StackLayout>
<Label
FontSize="Large"
FontAttributes="Bold"
Text="{Binding Title}"/>
<Label
Text="{Binding Subtitle}"/>
<ListView
x:Name="MiniSurveyListView"
HasUnevenRows="True"
ItemTemplate="{StaticResource questionViewCellTemplateSelector}">
</ListView>
<Label
Text="{Binding Footer}"/>
<Button
IsEnabled="False"
Command="{Binding OnButtonClicked}"
Text="OK"/>
</StackLayout>
</Frame>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,95 @@
using System;
using System.Threading.Tasks;
using TINK.ViewModel.MiniSurvey;
using Xamarin.CommunityToolkit.Extensions;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.MiniSurvey
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MiniSurveyPage : ContentPage, IViewService
{
public MiniSurveyPage()
{
var model = App.ModelRoot;
var vm = new MiniSurveyViewModel(
() => model.GetIsConnected(),
(isConnected) => model.GetConnector(isConnected),
this);
InitializeComponent();
BindingContext = vm;
MiniSurveyListView.ItemsSource = vm;
}
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strCancel">Type of buttons.</param>
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strAccept">Text of accept button.</param>
/// <param name="p_strCancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushModalAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync() => Navigation.PopModalAsync();
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
#if USCSHARP9
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#else
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#endif
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="TINK.View.MiniSurvey.Question.CheckOneViewCell">
<ViewCell.View>
<Frame>
<StackLayout>
<Label
FontSize="Medium"
Text="{Binding QuestionText}" />
<Picker
Title="{x:Static resources:AppResources.MiniSurveyAskForAnswer}"
SelectedItem="{Binding AnswerText}"
ItemsSource="{Binding AnswersText}"/>
</StackLayout>
</Frame>
</ViewCell.View>
</ViewCell>

View file

@ -0,0 +1,14 @@
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.MiniSurvey.Question
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CheckOneViewCell : ViewCell
{
public CheckOneViewCell ()
{
InitializeComponent ();
}
}
}

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
x:Class="TINK.View.MiniSurvey.Question.FreeTextViewCell">
<ViewCell.View>
<Frame>
<StackLayout>
<Label
FontSize="Medium"
Text="{Binding QuestionText}" />
<Editor
AutoSize="TextChanges"
Text="{Binding AnswerText}"
Placeholder="{x:Static resources:AppResources.MiniSurveyEnterAnswer}">
</Editor>
</StackLayout>
</Frame>
</ViewCell.View>
</ViewCell>

View file

@ -0,0 +1,15 @@

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.MiniSurvey.Question
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FreeTextViewCell : ViewCell
{
public FreeTextViewCell ()
{
InitializeComponent ();
}
}
}

View file

@ -0,0 +1,26 @@
using Xamarin.Forms;
namespace TINK.View.MiniSurvey.Question
{
/// <summary>
/// Selects different templates for different question types.
/// </summary>
public class QuestionViewCellTemplateSelector : DataTemplateSelector
{
DataTemplate checkOneViewCell;
DataTemplate freeTextViewCell;
public QuestionViewCellTemplateSelector()
{
checkOneViewCell = new DataTemplate(typeof(CheckOneViewCell));
freeTextViewCell = new DataTemplate(typeof(FreeTextViewCell));
}
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return item is ViewModel.MiniSurvey.Question.FreeTextViewModel
? freeTextViewCell
: checkOneViewCell;
}
}
}

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.MyBikes.MyBikesPage"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
xmlns:local_bike="clr-namespace:TINK.View.Bike"
Title="{x:Static resources:AppResources.MarkingMyBikes}">
<ContentPage.Resources>
<ResourceDictionary>
<local_bike:BikeViewCellTemplateSelector x:Key="bikeTemplateSelector"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<Frame>
<StackLayout>
<ListView
x:Name="MyBikesListView"
SelectionMode="None"
SelectedItem="{Binding SelectedBike}"
IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/>
<StackLayout
VerticalOptions="EndAndExpand"
Orientation="Horizontal">
<Label
IsVisible="{Binding IsNoBikesOccupiedVisible}"
VerticalOptions="StartAndExpand"
Text="{Binding NoBikesOccupiedText}"/>
<Label
HeightRequest="20"
Text="{Binding StatusInfoText}"
VerticalOptions="Center"
HorizontalOptions="FillAndExpand"/>
<ActivityIndicator IsRunning="{Binding IsRunning}"
IsVisible="{Binding IsRunning}"
HeightRequest="20"
VerticalOptions="CenterAndExpand"
HorizontalOptions="End">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double" iOS="40" Android="40" WinPhone="40" />
</ActivityIndicator.WidthRequest>
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color"
iOS="#2499CE" WinPhone="#2499CE" />
</ActivityIndicator.Color>
</ActivityIndicator>
</StackLayout>
</StackLayout>
</Frame>
</ContentPage.Content>
</ContentPage>

View file

@ -0,0 +1,169 @@
using Plugin.Connectivity;
using System;
using System.Threading;
using System.Threading.Tasks;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.MyBikes
{
using Serilog;
using TINK.ViewModel.MyBikes;
using Xamarin.CommunityToolkit.Extensions;
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyBikesPage : ContentPage, IViewService
{
/// <summary> Refernce to view model. </summary>
MyBikesPageViewModel m_oViewModel = null;
/// <summary>
/// Constructs a my bikes page.
/// </summary>
public MyBikesPage()
{
}
/// <summary>
/// Invoked when page is shown.
/// Starts update process.
/// </summary>
protected async override void OnAppearing()
{
if (m_oViewModel != null)
{
// No need to create view model, set binding context an items source if already done.
// If done twice tap events are fired multiple times (when hiding page using home button).
await m_oViewModel.OnAppearing();
return;
}
try
{
var model = App.ModelRoot;
// Backup synchronization context when called from GUI-thread.
var synchronizationContext = SynchronizationContext.Current;
m_oViewModel = new MyBikesPageViewModel(
model.ActiveUser,
App.PermissionsService,
App.BluetoothService,
Device.RuntimePlatform,
() => model.GetIsConnected(),
(isConnected) => model.GetConnector(isConnected),
App.GeolocationServicesContainer.Active,
model.LocksServices.Active,
model.Polling,
(d, obj) => synchronizationContext.Post(d, obj),
model.SmartDevice,
this)
{
IsReportLevelVerbose = model.IsReportLevelVerbose
};
}
catch (Exception exception)
{
Log.ForContext<MyBikesPage>().Error("Displaying bikes at station page failed. {Exception}", exception);
await DisplayAlert("Fehler", $"Seite Räder an Station kann nicht angezeigt werden. ${exception.Message}", "OK");
return;
}
InitializeComponent();
BindingContext = m_oViewModel;
MyBikesListView.ItemsSource = m_oViewModel;
await m_oViewModel.OnAppearing();
}
/// <summary>
/// Invoked when pages is closed/ hidden.
/// Stops update process.
/// </summary>
protected async override void OnDisappearing()
{
if (m_oViewModel == null)
{
// View model might be null (Example: Occured when page to querry for location permissions was opened)
return;
}
await m_oViewModel.OnDisappearing();
}
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strCancel">Type of buttons.</param>
public new async Task DisplayAlert(string p_strTitle, string p_strMessage, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strCancel);
/// <summary> Displays alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="cancel">Type of buttons.</param>
public async Task DisplayAdvancedAlert(
string title,
string message,
string details,
string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", cancel);
/// <summary> Displays detailed alert message.</summary>
/// <param name="title">Title of message.</param>
/// <param name="message">Message to display.</param>
/// <param name="details">Detailed error description.</param>
/// <param name="accept">Text of accept button.</param>
/// <param name="cancel">Text of cancel button.</param>
/// <returns>True if user pressed accept.</returns>
public async Task<bool> DisplayAdvancedAlert(string title, string message, string details, string accept, string cancel)
=> await App.Current.MainPage.DisplayAlert(title, $"{message}\r\nDetails:\r\n{details}", accept, cancel);
/// <summary>
/// Displays alert message.
/// </summary>
/// <param name="p_strTitle">Title of message.</param>
/// <param name="p_strMessage">Message to display.</param>
/// <param name="p_strAccept">Text of accept button.</param>
/// <param name="p_strCancel">Text of button.</param>
/// <returns>True if user pressed accept.</returns>
public new async Task<bool> DisplayAlert(string p_strTitle, string p_strMessage, string p_strAccept, string p_strCancel)
=> await App.Current.MainPage.DisplayAlert(p_strTitle, p_strMessage, p_strAccept, p_strCancel);
#if USEFLYOUT
public void ShowPage(ViewTypes p_oType, string p_strTitle = null)
=> throw new NotImplementedException();
#else
/// <summary> Shows a page.</summary>
/// <param name="route">Route of the page to show.</param>
public async Task ShowPage(string route) => await Shell.Current.GoToAsync(route);
#endif
/// <summary> Pushes a page onto the modal stack. </summary>
/// <param name="typeOfPage">Page to display.</param>
public async Task PushModalAsync(ViewTypes typeOfPage)
=> await Navigation.PushModalAsync((Page)Activator.CreateInstance(typeOfPage.GetViewType()));
/// <summary> Pops a page from the modal stack. </summary>
public Task PopModalAsync() => throw new NotSupportedException();
/// <summary> Pushes a page onto the stack. </summary>
/// <param name="p_oTypeOfPage">Page to display.</param>
public Task PushAsync(ViewTypes p_oTypeOfPage) => throw new NotSupportedException();
#if USCSHARP9
public async Task<IViewService.IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#else
public async Task<IUserFeedback> DisplayUserFeedbackPopup() => await Navigation.ShowPopupAsync<FeedbackPopup.Result>(new FeedbackPopup());
#endif
}
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<FlyoutPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.Root.RootPage"
xmlns:pages="clr-namespace:TINK.View.Root"
xmlns:mappage="clr-namespace:TINK.View.Map">
<FlyoutPage.Flyout>
<pages:RootPageFlyout x:Name="FlyoutPage" />
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage>
<x:Arguments>
<mappage:MapPage />
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
</FlyoutPage>

View file

@ -0,0 +1,95 @@
using System;
using TINK.Model.Station;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Root
{
/// <summary>
/// Mamages creation of detail pages if a flyout page menu entry is selected.
/// Exposes flyout page style navigation which is used by detail pages.
/// </summary>
/// <remarks>
/// Examples of use cases when detail pages do navigation:
// - switch to map page after succesfully logging in/ logging out
// - switch to login page form bikes at station page if not yet logged in
/// </remarks>
[XamlCompilation(XamlCompilationOptions.Compile)]
#if USEFLYOUT
public partial class RootPage : FlyoutPage, INavigationMasterDetail
#else
public partial class RootPage : FlyoutPage
#endif
{
public RootPage()
{
InitializeComponent();
FlyoutPage.ListView.ItemSelected += OnListViewItemSelected;
// Any type of split behaviour conflics with map shifting functionality (assuming FlyoutPage behaves same like MasterDetailPage).
FlyoutLayoutBehavior = FlyoutLayoutBehavior.Popover;
var navigationPage = Detail as NavigationPage;
if (navigationPage == null)
{
return;
}
#if USEFLYOUT
var detailPage = navigationPage.RootPage as IDetailPage;
if (detailPage == null)
{
return;
}
detailPage.NavigationMasterDetail = this;
#endif
}
/// <summary>
/// Is called if a flyout page menu entry is selected.
/// Creates a new page.
/// </summary>
private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
{
if (!(e.SelectedItem is RootPageFlyoutMenuItem item))
{
// Unexpected argument detected.
return;
}
// Set selected station to new
App.ModelRoot.SelectedStation = new NullStation();
ShowPage(item.TargetType, item.Title);
IsPresented = false;
FlyoutPage.ListView.SelectedItem = null;
}
/// <summary>
/// Shows a detail page.
/// </summary>
/// <param name="typeOfPage">Type of page to show.</param>
/// <param name="title">Title of page.</param>
public void ShowPage(Type typeOfPage, string title)
{
var page = (Page)Activator.CreateInstance(typeOfPage);
page.Title = title;
#if USEFLYOUT
if (page is IDetailPage detailPage)
{
// Detail page needs reference to perform navigation.
// Examples see above in xdoc of class.
detailPage.NavigationMasterDetail = this;
}
#endif
Detail = new NavigationPage(page);
}
}
}

View file

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TINK.View.Root.RootPageFlyout"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
xmlns:local="clr-namespace:TINK.View"
IconImageSource="menu"
Title="sharee.bike">
<StackLayout>
<ListView x:Name="MenuItemsListView"
SeparatorVisibility="None"
HasUnevenRows="true"
local:ListViewAttachedBehavior.Command="{Binding MenuItemSelected}"
ItemsSource="{Binding MenuItems}">
<ListView.Header>
<Grid BackgroundColor="{DynamicResource Key=primary-back-title-color}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="80"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Label
Grid.Column="1"
Grid.Row="2"
Text="{Binding MasterDetailMenuTitlte}"
Style="{DynamicResource SubtitleStyle}"/>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image>
<Image.Source>
<FontImageSource Glyph="{Binding GlyphCode}" Color="Black" FontFamily="FA-S"/>
</Image.Source>
</Image>
<Label
Grid.Column="1"
Margin="10, 0, 0, 0"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center"
FontSize="18"
Text="{Binding Title}"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>

View file

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using TINK.Model;
using TINK.Services;
#if USEFLYOUT
using TINK.View.MasterDetail;
#endif
using TINK.View.Themes;
using TINK.ViewModel.Root;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TINK.View.Root
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RootPageFlyout : ContentPage
{
public ListView ListView;
public RootPageFlyout()
{
InitializeComponent();
BindingContext = new RootPageFlyoutViewModel();
ListView = MenuItemsListView;
}
}
}

View file

@ -0,0 +1,20 @@
using System;
namespace TINK.View.Root
{
public class RootPageFlyoutMenuItem
{
public RootPageFlyoutMenuItem()
{
TargetType = typeof(RootPageFlyoutMenuItem);
}
public int Id { get; set; }
public string GlyphCode { get; set; }
public string Title { get; set; }
public Type TargetType { get; set; }
}
}

View file

@ -0,0 +1,42 @@
using System;
using TINK.View.Map;
using TINK.ViewModel.MasterDetail;
namespace TINK.View
{
public class MainPageMenuItem
{
public MainPageMenuItem()
{
TargetType = typeof(MapPage);
}
public MainPageMenuItem(
int p_iId,
Type p_oTypeOfPage,
string p_strTitle = null)
{
TargetType = p_oTypeOfPage;
Id = p_iId;
Title = p_strTitle ?? Helper.GetCaption(p_oTypeOfPage);
}
public int Id
{
get;
private set;
}
public string Title
{
get;
private set;
}
public Type TargetType
{
get;
private set;
}
}
}

View file

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
xmlns:mappage="clr-namespace:TINK.View.Map"
xmlns:findbike="clr-namespace:TINK.View.FindBike"
xmlns:mybikes="clr-namespace:TINK.View.MyBikes"
xmlns:account="clr-namespace:TINK.View.Account"
xmlns:login="clr-namespace:TINK.View.Login"
xmlns:settings="clr-namespace:TINK.View.Settings"
xmlns:contact="clr-namespace:TINK.View.Contact"
xmlns:info="clr-namespace:TINK.View.Info"
xmlns:header="clr-namespace:TINK.View.RootShell"
BackgroundColor="{DynamicResource Key=primary-back-title-color}"
Title="Shell"
x:Class="TINK.View.RootShell.AppShell">
<Shell.FlyoutHeader>
<header:FlyoutHeader/>
</Shell.FlyoutHeader>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{x:Static resources:AppResources.MarkingMapPage}"
Route="MapPage"
ContentTemplate="{DataTemplate mappage:MapPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconMap}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{x:Static resources:AppResources.MarkingFindBike}"
IsVisible="{Binding IsFindBikePageVisible}"
ContentTemplate="{DataTemplate findbike:FindBikePage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconFindBike}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{x:Static resources:AppResources.MarkingMyBikes}"
IsVisible="{Binding IsMyBikesPageVisible}"
ContentTemplate="{DataTemplate mybikes:MyBikesPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconMyBikes}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{x:Static resources:AppResources.MarkingAccount}"
IsVisible="{Binding IsAccountPageVisible}"
ContentTemplate="{DataTemplate account:AccountPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconAccount}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{x:Static resources:AppResources.MarkingLogin}"
Route="LoginPage"
IsVisible="{Binding IsLoginPageVisible}"
ContentTemplate="{DataTemplate login:LoginPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconLogin}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{x:Static resources:AppResources.MarkingSettings}"
IsVisible="{Binding IsSettingsPageVisible}"
ContentTemplate="{DataTemplate settings:SettingsPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconSettings}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{x:Static resources:AppResources.MarkingFeesAndBikes}"
ContentTemplate="{DataTemplate contact:FeesAndBikesPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconFeesAndBikes}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{x:Static resources:AppResources.MarkingFeedbackAndContact}"
ContentTemplate="{DataTemplate contact:ContactPage}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconContact}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
<FlyoutItem FlyoutDisplayOptions="AsMultipleItems">
<ShellContent
Title="{Binding TabbedPageIngoTitle}"
ContentTemplate="{DataTemplate info:TabbedPageInfo}">
<ShellContent.FlyoutIcon>
<FontImageSource Glyph="{StaticResource IconInfo}" Color="Black" FontFamily="FA-S" />
</ShellContent.FlyoutIcon>
</ShellContent>
</FlyoutItem>
</Shell>

View file

@ -0,0 +1,15 @@

using TINK.ViewModel.RootShell;
using Xamarin.Forms;
namespace TINK.View.RootShell
{
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
BindingContext = new AppShellViewModel();
}
}
}

View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
BackgroundColor="{DynamicResource Key=primary-back-title-color}"
x:Class="TINK.View.RootShell.FlyoutHeader">
<Grid Padding="5,10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Image
HeightRequest="140"
Aspect="AspectFit"
Source="sharee_no_background.png" />
<Label
HorizontalOptions="CenterAndExpand"
FontSize="Large"
Grid.Row="1"
Text="{Binding MasterDetailMenuTitlte}"/>
</Grid>
</ContentView>

Some files were not shown because too many files have changed in this diff Show more