feat: migrate to whole new data model and update relevant use
cases.
This commit is contained in:
parent
fba880e1be
commit
380be43c05
|
@ -135,3 +135,5 @@ AppDir/bundle/
|
|||
appimage-build/
|
||||
/*.AppImage
|
||||
.vscode/settings.json
|
||||
|
||||
*.patch
|
||||
|
|
14
docs/FRs.md
14
docs/FRs.md
|
@ -2,25 +2,27 @@
|
|||
|
||||
## user stories
|
||||
|
||||
The following user stories may not use formal terminology as [meta-arch.md](./meta-arch.md) and use cases(`test/*.feature`), but use oral descriptions.
|
||||
|
||||
* name: [PDF browser](../test/features/pdf_browser.feature)
|
||||
* role: user
|
||||
* functionality: view and navigate PDF documents
|
||||
* benefit: select page to add signature
|
||||
* name: [load signature picture](../test/features/load_signature_picture.feature)
|
||||
* name: [load signature](../test/features/load_signature.feature)
|
||||
* role: user
|
||||
* functionality: load a signature picture file
|
||||
* functionality: load a signature asset file and create a signature card
|
||||
* benefit: easily add signature to PDF
|
||||
* name: [geometrically adjust signature picture](../test/features/geometrically_adjust_signature_picture.feature)
|
||||
* role: user
|
||||
* functionality: adjust the size and position of the signature picture
|
||||
* functionality: adjust the scale, rotation and position of the signature placement on the PDF page
|
||||
* benefit: ensure the signature fits well on the PDF page
|
||||
* name: [graphically adjust signature picture](../test/features/graphically_adjust_signature_picture.feature)
|
||||
* role: user
|
||||
* functionality: background removal, contrast adjustment...
|
||||
* functionality: background removal, contrast adjustment... to enhance the appearance of the signature asset within the signature card
|
||||
* benefit: easily improve the appearance of the signature on the PDF without additional software.
|
||||
* name: [draw signature](../test/features/draw_signature.feature)
|
||||
* role: user
|
||||
* functionality: draw a signature using mouse or touch input
|
||||
* functionality: draw a signature asset using mouse or touch input
|
||||
* benefit: create a custom signature directly on the PDF if no pre-made signature is available.
|
||||
* name: [save signed PDF](../test/features/save_signed_pdf.feature)
|
||||
* role: user
|
||||
|
@ -28,7 +30,7 @@
|
|||
* benefit: easily keep a copy of the signed document for records.
|
||||
* name: [preferences for app](../test/features/app_preferences.feature)
|
||||
* role: user
|
||||
* functionality: configure app preferences such as `theme`, `language`.
|
||||
* functionality: configure app preferences such as `language`, `theme`, `theme-color`.
|
||||
* benefit: customize the app experience to better fit user needs
|
||||
* name: [remember preferences](../test/features/remember_preferences.feature)
|
||||
* role: user
|
||||
|
|
|
@ -11,6 +11,21 @@ The repo structure follows official [Package structure](https://docs.flutter.dev
|
|||
* `test/widget/` contains UI widget(component) tests which focus on `View` from MVVM of each component.
|
||||
* `integration_test/` for integration tests. They should be volatile to follow UI layout changes.
|
||||
|
||||
## Abstraction
|
||||
|
||||
### terminology
|
||||
|
||||
* signature asset
|
||||
* image file of a signature, stored in the device or cloud storage
|
||||
* can drawing from canvas
|
||||
* signature card
|
||||
* template of signature placement
|
||||
* It will include modifications such as brightness, contrast, background removal, rotation of the signature asset.
|
||||
* signature placement
|
||||
* placed modified signature asset from signature card on a specific position on a specific page of a specific PDF document
|
||||
* document
|
||||
* PDF document to be signed
|
||||
|
||||
## key dependencies
|
||||
|
||||
* [pdfrx](https://pub.dev/packages/pdfrx)
|
||||
|
|
|
@ -1,32 +1,80 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/// A simple library of signature images available to the user in the sidebar.
|
||||
class SignatureAsset {
|
||||
final String id; // unique id
|
||||
final Uint8List bytes;
|
||||
// List<List<Offset>>? strokes;
|
||||
final String? name; // optional display name (e.g., filename)
|
||||
const SignatureAsset({required this.id, required this.bytes, this.name});
|
||||
}
|
||||
|
||||
class GraphicAdjust {
|
||||
final double contrast;
|
||||
final double brightness;
|
||||
final bool bgRemoval;
|
||||
|
||||
const GraphicAdjust({
|
||||
this.contrast = 1.0,
|
||||
this.brightness = 0.0,
|
||||
this.bgRemoval = false,
|
||||
});
|
||||
|
||||
GraphicAdjust copyWith({
|
||||
double? contrast,
|
||||
double? brightness,
|
||||
bool? bgRemoval,
|
||||
}) => GraphicAdjust(
|
||||
contrast: contrast ?? this.contrast,
|
||||
brightness: brightness ?? this.brightness,
|
||||
bgRemoval: bgRemoval ?? this.bgRemoval,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* signature card is template of signature placement
|
||||
*/
|
||||
class SignatureCard {
|
||||
final double rotationDeg;
|
||||
final SignatureAsset asset;
|
||||
|
||||
GraphicAdjust graphicAdjust;
|
||||
|
||||
SignatureCard({required this.rotationDeg, required this.asset})
|
||||
: graphicAdjust = GraphicAdjust();
|
||||
}
|
||||
|
||||
/// Represents a single signature placement on a page combining both the
|
||||
/// geometric rectangle (UI coordinate space) and the identifier of the
|
||||
/// image/signature asset assigned to that placement.
|
||||
class SignaturePlacement {
|
||||
// The bounding box of this placement in UI coordinate space, implies scaling and position.
|
||||
final Rect rect;
|
||||
|
||||
/// from `SignatureCard`
|
||||
/// Rotation in degrees to apply when rendering/exporting this placement.
|
||||
final double rotationDeg;
|
||||
GraphicAdjust graphicAdjust;
|
||||
final SignatureAsset asset;
|
||||
|
||||
/// Identifier of the image (e.g., filename / asset id) assigned to this placement.
|
||||
/// Nullable to allow a placement reserved before an image is chosen.
|
||||
final String? imageId;
|
||||
const SignaturePlacement({
|
||||
SignaturePlacement({
|
||||
required this.rect,
|
||||
this.imageId,
|
||||
required this.asset,
|
||||
this.rotationDeg = 0.0,
|
||||
});
|
||||
GraphicAdjust graphicAdjust = const GraphicAdjust(),
|
||||
}) : graphicAdjust = graphicAdjust;
|
||||
|
||||
SignaturePlacement copyWith({
|
||||
Rect? rect,
|
||||
String? imageId,
|
||||
double? rotationDeg,
|
||||
required Rect rect,
|
||||
required SignatureAsset asset,
|
||||
double rotationDeg = 0.0,
|
||||
GraphicAdjust graphicAdjust = const GraphicAdjust(),
|
||||
}) => SignaturePlacement(
|
||||
rect: rect ?? this.rect,
|
||||
imageId: imageId ?? this.imageId,
|
||||
rotationDeg: rotationDeg ?? this.rotationDeg,
|
||||
rect: rect,
|
||||
asset: asset,
|
||||
rotationDeg: rotationDeg,
|
||||
graphicAdjust: graphicAdjust,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:typed_data';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:pdf_signature/l10n/app_localizations.dart';
|
||||
import 'package:pdf_signature/data/model/model.dart';
|
||||
|
||||
import '../../../../data/services/export_providers.dart';
|
||||
import '../../signature/view_model/signature_controller.dart';
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
/// A simple library of signature images available to the user in the sidebar.
|
||||
class SignatureAsset {
|
||||
final String id; // unique id
|
||||
final Uint8List bytes;
|
||||
final String? name; // optional display name (e.g., filename)
|
||||
const SignatureAsset({required this.id, required this.bytes, this.name});
|
||||
}
|
||||
import 'package:pdf_signature/data/model/model.dart';
|
||||
|
||||
class SignatureLibraryController extends StateNotifier<List<SignatureAsset>> {
|
||||
SignatureLibraryController() : super(const []);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import '../view_model/signature_library.dart';
|
||||
import 'package:pdf_signature/data/model/model.dart';
|
||||
import 'signature_drag_data.dart';
|
||||
import 'rotated_signature_image.dart';
|
||||
import 'package:pdf_signature/l10n/app_localizations.dart';
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
Feature: draw signature
|
||||
Feature: draw signature asset
|
||||
|
||||
Scenario: Draw with mouse or touch and place on page
|
||||
Given an empty signature canvas
|
||||
When the user draws strokes and confirms
|
||||
Then a signature image is created
|
||||
And it is placed on the selected page
|
||||
Then a signature asset is created
|
||||
And signature placement occurs on the selected page
|
||||
|
||||
Scenario: Clear and redraw
|
||||
Given a drawn signature exists in the canvas
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
Feature: geometrically adjust signature picture
|
||||
Feature: geometrically adjust signature asset
|
||||
|
||||
Scenario: Resize and move the signature within page bounds
|
||||
Given a signature image is placed on the page
|
||||
Given a signature asset is placed on the page
|
||||
When the user drags handles to resize and drags to reposition
|
||||
Then the size and position update in real time
|
||||
And the signature remains within the page area
|
||||
And the signature placement remains within the page area
|
||||
|
||||
Scenario: Lock aspect ratio while resizing
|
||||
Given a signature image is selected
|
||||
When the user enables aspect ratio lock and resizes
|
||||
Then the image scales proportionally
|
||||
Scenario: Rotate the signature
|
||||
Given a signature asset is placed on the page
|
||||
When the user uses rotate controls
|
||||
Then the signature placement rotates around its center in real time
|
||||
And resize to fit within bounding box
|
|
@ -1,13 +1,13 @@
|
|||
Feature: graphically adjust signature picture
|
||||
Feature: graphically adjust signature asset
|
||||
|
||||
Scenario: Remove background
|
||||
Given a signature image is selected
|
||||
Given a signature asset is selected
|
||||
When the user enables background removal
|
||||
Then near-white background becomes transparent in the preview
|
||||
And the user can apply the change
|
||||
|
||||
Scenario: Adjust contrast and brightness
|
||||
Given a signature image is selected
|
||||
Given a signature asset is selected
|
||||
When the user changes contrast and brightness controls
|
||||
Then the preview updates immediately
|
||||
And the user can apply or reset adjustments
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Feature: load signature asset
|
||||
|
||||
Scenario Outline: Handle invalid or unsupported files
|
||||
Given the user selects "<file>"
|
||||
When the app attempts to load the asset
|
||||
Then the user is notified of the issue
|
||||
And the asset is not added to the document
|
||||
|
||||
Examples:
|
||||
| file |
|
||||
| 'corrupted.png' |
|
||||
| 'signature.bmp' |
|
||||
| 'empty.jpg' |
|
||||
|
||||
Scenario: Import a signature asset
|
||||
When the user chooses a image file as a signature asset
|
||||
Then the asset is loaded and shown as a signature asset
|
||||
|
||||
Scenario: Import a signature card
|
||||
When the user chooses a signature asset to created a signature card
|
||||
Then the asset is loaded and shown as a signature card
|
||||
|
||||
Scenario: Import a signature placement
|
||||
Given a created signature card
|
||||
When the user drags this signature card on the page of the document to place a signature placement
|
||||
Then a signature placement appears on the page based on the signature card
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
Feature: load signature picture
|
||||
|
||||
Scenario: Import a signature image
|
||||
Given a PDF page is selected for signing
|
||||
When the user chooses a signature image file
|
||||
Then the image is loaded and shown as a signature asset
|
||||
|
||||
Scenario Outline: Handle invalid or unsupported files
|
||||
Given the user selects "<file>"
|
||||
When the app attempts to load the image
|
||||
Then the user is notified of the issue
|
||||
And the image is not added to the document
|
||||
|
||||
Examples:
|
||||
| file |
|
||||
| 'corrupted.png' |
|
||||
| 'signature.bmp' |
|
||||
| 'empty.jpg' |
|
|
@ -1,9 +1,9 @@
|
|||
Feature: PDF browser
|
||||
Feature: document browser
|
||||
|
||||
Background:
|
||||
Given a sample multi-page PDF (5 pages) is available
|
||||
Given a sample multi-page document (5 pages) is available
|
||||
|
||||
Scenario: Open a PDF and navigate pages
|
||||
Scenario: Open a document and navigate pages
|
||||
When the user opens the document
|
||||
Then the first page is displayed
|
||||
And the user can move to the next or previous page
|
||||
|
@ -47,6 +47,6 @@ Feature: PDF browser
|
|||
Then the last page is displayed (page {5})
|
||||
And the page label shows "Page {5} of {5}"
|
||||
|
||||
Scenario: Go to is disabled when no PDF is loaded
|
||||
Scenario: Go to is disabled when no document is loaded
|
||||
Given no document is open
|
||||
Then the Go to input cannot be used
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
Feature: save signed PDF
|
||||
Feature: save signed document
|
||||
|
||||
Scenario: Export the signed document to a new file
|
||||
Given a PDF is open and contains at least one placed signature
|
||||
Given a document is open and contains at least one signature placement
|
||||
When the user saves/exports the document
|
||||
Then a new PDF file is saved at specified full path, location and file name
|
||||
And the signatures appear on the corresponding page in the output
|
||||
Then a new document file is saved at specified full path, location and file name
|
||||
And the signature placements appear on the corresponding page in the output
|
||||
And keep other unchanged content(pages) intact in the output
|
||||
|
||||
Scenario: Vector-accurate stamping into PDF page coordinates
|
||||
Given a signature is placed with a position and size relative to the page
|
||||
Given a signature placement is placed with a position and size relative to the page
|
||||
When the user saves/exports the document
|
||||
Then the signature is stamped at the exact PDF page coordinates and size
|
||||
Then the signature placement is stamped at the exact PDF page coordinates and size
|
||||
And the stamp remains crisp at any zoom level (not rasterized by the screen)
|
||||
And other page content remains vector and unaltered
|
||||
|
||||
Scenario: Prevent saving when nothing is placed
|
||||
Given a PDF is open with no signatures placed
|
||||
Given a document is open with no signature placements placed
|
||||
When the user attempts to save
|
||||
Then the user is notified there is nothing to save
|
||||
|
||||
Scenario: Loading sign when exporting/saving files
|
||||
Given a signature is placed with a position and size relative to the page
|
||||
Given a signature placement is placed with a position and size relative to the page
|
||||
When the user starts exporting the document
|
||||
And the export process is not yet finished
|
||||
Then the user is notified that the export is still in progress
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
Feature: support multiple signature pictures
|
||||
Feature: support multiple signature assets
|
||||
|
||||
Scenario: Place signatures on different pages with different images
|
||||
Given a multi-page PDF is open
|
||||
When the user places a signature from picture <first_image> on page <first_page>
|
||||
And the user places a signature from picture <second_image> on page <second_page>
|
||||
Then both signatures are shown on their respective pages
|
||||
Scenario: Place signature placements on different pages with different assets
|
||||
Given a multi-page document is open
|
||||
When the user places a signature placement from asset <first_asset> on page <first_page>
|
||||
And the user places a signature placement from asset <second_asset> on page <second_page>
|
||||
Then both signature placements are shown on their respective pages
|
||||
Examples:
|
||||
# Same page, same image
|
||||
# Same page, different images
|
||||
# Different pages, same image
|
||||
# Different pages, different images
|
||||
| first_image | first_page | second_image | second_page |
|
||||
# Same page, same asset
|
||||
# Same page, different assets
|
||||
# Different pages, same asset
|
||||
# Different pages, different assets
|
||||
| first_asset | first_page | second_asset | second_page |
|
||||
| 'alice.png' | 1 | 'alice.png' | 1 |
|
||||
| 'alice.png' | 1 | 'bob.png' | 1 |
|
||||
| 'alice.png' | 1 | 'bob.png' | 3 |
|
||||
| 'bob.png' | 2 | 'alice.png' | 5 |
|
||||
|
||||
Scenario: Reuse the same image for more than one signature
|
||||
Given a signature image is loaded or drawn
|
||||
Scenario: Reuse the same asset for more than one signature placement
|
||||
Given a signature asset is loaded or drawn
|
||||
When the user places it in multiple locations in the document
|
||||
Then identical signature instances appear in each location
|
||||
And adjusting one instance does not affect the others
|
||||
|
||||
Scenario: Save/export uses the assigned image for each signature
|
||||
Given a PDF is open and contains multiple placed signatures across pages
|
||||
Scenario: Save/export uses the assigned asset for each signature placement
|
||||
Given a document is open and contains multiple placed signature placements across pages
|
||||
When the user saves/exports the document
|
||||
Then all placed signatures appear on their corresponding pages in the output
|
||||
Then all placed signature placements appear on their corresponding pages in the output
|
||||
And other page content remains unaltered
|
||||
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
Feature: support multiple signatures
|
||||
Feature: support multiple signature placements
|
||||
|
||||
Scenario: Place signatures on different pages
|
||||
Given a multi-page PDF is open
|
||||
When the user places a signature on page {1}
|
||||
And the user navigates to page {3} and places another signature
|
||||
Then both signatures are shown on their respective pages
|
||||
Scenario: Place signature placements on different pages
|
||||
Given a multi-page document is open
|
||||
When the user places a signature placement on page {1}
|
||||
And the user navigates to page {3} and places another signature placement
|
||||
Then both signature placements are shown on their respective pages
|
||||
|
||||
Scenario: Place multiple signatures on the same page independently
|
||||
Given a PDF page is selected for signing
|
||||
When the user places two signatures on the same page
|
||||
Then each signature can be dragged and resized independently
|
||||
Scenario: Place multiple signature placements on the same page independently
|
||||
Given a document page is selected for signing
|
||||
When the user places two signature placements on the same page
|
||||
Then each signature placement can be dragged and resized independently
|
||||
And dragging or resizing one does not change the other
|
||||
|
||||
Scenario: Reuse the same signature asset in multiple locations
|
||||
Given a signature image is loaded or drawn
|
||||
When the user places it in multiple locations in the document
|
||||
Then identical signature instances appear in each location
|
||||
And adjusting one instance does not affect the others
|
||||
Given a signature asset loaded or drawn is wrapped in a signature card
|
||||
When the user drags it on the page of the document to place signature placements in multiple locations in the document
|
||||
Then identical signature placements appear in each location
|
||||
And adjusting one of the signature placements does not affect the others
|
||||
|
||||
Scenario: Remove one of many signatures
|
||||
Given three signatures are placed on the current page
|
||||
When the user deletes one selected signature
|
||||
Then only the selected signature is removed
|
||||
And the other signatures remain unchanged
|
||||
Scenario: Remove one of many signature placements
|
||||
Given three signature placements are placed on the current page
|
||||
When the user deletes one selected signature placement
|
||||
Then only the selected signature placement is removed
|
||||
And the other signature placements remain unchanged
|
||||
|
||||
Scenario: Keep earlier signatures while navigating between pages
|
||||
Given a signature is placed on page {2}
|
||||
When the user navigates to page {5} and places another signature
|
||||
Then the signature on page {2} remains
|
||||
And the signature on page {5} is shown on page {5}
|
||||
Scenario: Keep earlier signature placements while navigating between pages
|
||||
Given a signature placement is placed on page {2}
|
||||
When the user navigates to page {5} and places another signature placement
|
||||
Then the signature placement on page {2} remains
|
||||
And the signature placement on page {5} is shown on page {5}
|
||||
|
||||
Scenario: Save a document with multiple signatures across pages
|
||||
Given a PDF is open and contains multiple placed signatures across pages
|
||||
Scenario: Save a document with multiple signature placements across pages
|
||||
Given a document is open and contains multiple placed signature placements across pages
|
||||
When the user saves/exports the document
|
||||
Then all placed signatures appear on their corresponding pages in the output
|
||||
Then all placed signature placements appear on their corresponding pages in the output
|
||||
And other page content remains unaltered
|
||||
|
||||
|
|
Loading…
Reference in New Issue